bridgetown-core 1.0.0.alpha7 → 1.0.0.alpha11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -0
  3. data/bin/bridgetown +8 -1
  4. data/bridgetown-core.gemspec +2 -1
  5. data/lib/bridgetown-core/collection.rb +6 -6
  6. data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +7 -0
  7. data/lib/bridgetown-core/commands/console.rb +39 -12
  8. data/lib/bridgetown-core/commands/doctor.rb +8 -5
  9. data/lib/bridgetown-core/commands/plugins.rb +1 -1
  10. data/lib/bridgetown-core/concerns/site/extensible.rb +8 -0
  11. data/lib/bridgetown-core/concerns/site/processable.rb +22 -4
  12. data/lib/bridgetown-core/concerns/site/ssr.rb +2 -17
  13. data/lib/bridgetown-core/configurations/minitesting.rb +1 -1
  14. data/lib/bridgetown-core/configurations/render/render.yaml.erb +3 -0
  15. data/lib/bridgetown-core/converters/erb_templates.rb +1 -1
  16. data/lib/bridgetown-core/converters/serbea_templates.rb +71 -0
  17. data/lib/bridgetown-core/drops/drop.rb +1 -1
  18. data/lib/bridgetown-core/drops/resource_drop.rb +28 -5
  19. data/lib/bridgetown-core/generators/prototype_generator.rb +3 -3
  20. data/lib/bridgetown-core/hooks.rb +51 -20
  21. data/lib/bridgetown-core/liquid_renderer/file_system.rb +1 -3
  22. data/lib/bridgetown-core/model/base.rb +24 -1
  23. data/lib/bridgetown-core/model/repo_origin.rb +48 -0
  24. data/lib/bridgetown-core/plugin_manager.rb +2 -2
  25. data/lib/bridgetown-core/rack/roda.rb +4 -5
  26. data/lib/bridgetown-core/rack/routes.rb +44 -10
  27. data/lib/bridgetown-core/rack/static_indexes.rb +2 -0
  28. data/lib/bridgetown-core/resource/base.rb +2 -0
  29. data/lib/bridgetown-core/utils/loaders_manager.rb +11 -0
  30. data/lib/bridgetown-core/utils.rb +25 -21
  31. data/lib/bridgetown-core/version.rb +1 -1
  32. data/lib/bridgetown-core/watcher.rb +64 -60
  33. data/lib/bridgetown-core.rb +0 -1
  34. metadata +31 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e8dceaa24615a3a0de23c469444c2d22b36ce1f2c171177a9d20646f7b31446
4
- data.tar.gz: 10c6c7e5c3bfc2a1f591d8953d098dae8d0d90942bb1ad6ef7871834cf658434
3
+ metadata.gz: '09c13a3ec4bb37595ede90e5536eca3159812d06c482397d971d1130eab3ceab'
4
+ data.tar.gz: 48cd4b6488ba57a185e510f00e6986b8514ad33887b7710431c40d9efcae4f45
5
5
  SHA512:
6
- metadata.gz: 254a0d29eca611c8642acf2f664ace0dc8de883cf38dd00f56597dfc273625460089743e5ebc8e81df231035a8a1365393a5e890c1c4b1447d94fba48e310a2f
7
- data.tar.gz: 48c9518b97fc1e890d8b04b908a117296def616657831c7d0572e9e611a58d3381870f9257f17303db965fa40d47b2280b3e2b814f02652b0b374e6ab4ab0f0d
6
+ metadata.gz: '008f32b43e009a8349bc69fe01277c9a7ebdef2c7062d8c0dc331826d0eac394491a75b48892629d5a835eeef12e435c573d4c811ec33441555ec820870157d6'
7
+ data.tar.gz: b6cf7933d50093c1332b1b39f5764768a3d8cdc3ff91b115e3d31790afa350826815f30e7d3e8c3891ddffea236f40b8e5b52268ec8eb019b4e20f319f1171ef
data/.rubocop.yml CHANGED
@@ -11,6 +11,7 @@ AllCops:
11
11
  - vendor/**/*
12
12
  - tmp/**/*
13
13
  - test/source/**/*
14
+ - test/resources/src/_pages/*.rb
14
15
  - lib/site_template/Rakefile
15
16
  - lib/site_template/config.ru
16
17
  - lib/site_template/config/**/*
@@ -30,6 +31,10 @@ Performance/CollectionLiteralInLoop:
30
31
  Exclude:
31
32
  - test/test_filters.rb
32
33
 
34
+ Style/OpenStructUse:
35
+ Exclude:
36
+ - test/**/*.rb
37
+
33
38
  Style/StringConcatenation:
34
39
  Exclude:
35
40
  - test/test_apply_command.rb
data/bin/bridgetown CHANGED
@@ -19,11 +19,18 @@ Bridgetown::PluginManager.require_from_bundler
19
19
  # TODO: need to change behavior of Colorator gem
20
20
  ENV["THOR_SHELL"] = "Basic" if ENV["NO_COLOR"]
21
21
 
22
- output_version = if ARGV[0] == "-v"
22
+ output_version = if ARGV[0] == "-v" || ARGV[0] == "--version"
23
23
  puts "bridgetown #{Bridgetown::VERSION} \"#{Bridgetown::CODE_NAME}\""
24
24
  true
25
25
  end
26
26
 
27
+ if env_index = ARGV.index { |arg| arg == "-e" } # rubocop:disable Lint/AssignmentInCondition
28
+ env = ARGV[env_index + 1]
29
+ ENV["BRIDGETOWN_ENV"] = env if env
30
+ elsif env_flag = ARGV.find { |arg| arg.start_with?("--environment=") } # rubocop:disable Lint/AssignmentInCondition
31
+ ENV["BRIDGETOWN_ENV"] = env_flag.split("=").last
32
+ end
33
+
27
34
  ENV["RACK_ENV"] = ENV["BRIDGETOWN_ENV"]
28
35
 
29
36
  require "bridgetown-core/commands/base"
@@ -43,14 +43,15 @@ Gem::Specification.new do |s|
43
43
  s.add_runtime_dependency("kramdown", "~> 2.1")
44
44
  s.add_runtime_dependency("kramdown-parser-gfm", "~> 1.0")
45
45
  s.add_runtime_dependency("liquid", "~> 5.0")
46
- s.add_runtime_dependency("liquid-component", ">= 0.1")
47
46
  s.add_runtime_dependency("listen", "~> 3.0")
48
47
  s.add_runtime_dependency("rack-indifferent", ">= 1.2.0")
49
48
  s.add_runtime_dependency("rake", ">= 13.0")
50
49
  s.add_runtime_dependency("roda", "~> 3.46")
51
50
  s.add_runtime_dependency("rouge", "~> 3.0")
51
+ s.add_runtime_dependency("serbea", "~> 1.0")
52
52
  s.add_runtime_dependency("terminal-table", "~> 1.8")
53
53
  s.add_runtime_dependency("thor", "~> 1.1")
54
54
  s.add_runtime_dependency("tilt", "~> 2.0")
55
55
  s.add_runtime_dependency("webrick", "~> 1.7")
56
+ s.add_runtime_dependency("zeitwerk", "~> 2.5")
56
57
  end
@@ -297,12 +297,6 @@ module Bridgetown
297
297
  resources << resource if site.config.unpublished || resource.published?
298
298
  end
299
299
 
300
- private
301
-
302
- def container
303
- @container ||= site.config["collections_dir"]
304
- end
305
-
306
300
  def sort_resources!
307
301
  if metadata["sort_by"].is_a?(String)
308
302
  sort_resources_by_key!
@@ -312,6 +306,12 @@ module Bridgetown
312
306
  resources.reverse! if metadata.sort_direction == "descending"
313
307
  end
314
308
 
309
+ private
310
+
311
+ def container
312
+ @container ||= site.config["collections_dir"]
313
+ end
314
+
315
315
  # A custom sort function based on Schwartzian transform
316
316
  # Refer https://byparker.com/blog/2017/schwartzian-transform-faster-sorting/ for details
317
317
  def sort_resources_by_key!
@@ -3,6 +3,13 @@
3
3
  module Bridgetown
4
4
  module Commands
5
5
  module ConfigurationOverridable
6
+ def self.included(klass)
7
+ desc = "The environment used for this command (aka development, test, production, etc.)"
8
+ klass.class_option :environment,
9
+ aliases: "-e",
10
+ desc: desc
11
+ end
12
+
6
13
  # Create a full Bridgetown configuration with the options passed in as overrides
7
14
  #
8
15
  # options - the configuration overrides
@@ -1,6 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
+ module ConsoleMethods
5
+ def site
6
+ Bridgetown::Current.site
7
+ end
8
+
9
+ def collections
10
+ site.collections
11
+ end
12
+
13
+ def reload!
14
+ Bridgetown.logger.info "Reloading site..."
15
+
16
+ I18n.reload! # make sure any locale files get read again
17
+ Bridgetown::Hooks.trigger :site, :pre_reload, site
18
+ Bridgetown::Hooks.clear_reloadable_hooks
19
+ site.plugin_manager.reload_plugin_files
20
+ site.loaders_manager.reload_loaders
21
+ Bridgetown::Hooks.trigger :site, :post_reload, site
22
+
23
+ ConsoleMethods.site_reset(site)
24
+ end
25
+
26
+ def self.site_reset(site)
27
+ site.reset
28
+ Bridgetown.logger.info "Reading files..."
29
+ site.read
30
+ Bridgetown.logger.info "", "done!"
31
+ Bridgetown.logger.info "Running generators..."
32
+ site.generate
33
+ Bridgetown.logger.info "", "done!"
34
+ end
35
+ end
36
+
4
37
  module Commands
5
38
  class Console < Thor::Group
6
39
  extend Summarizable
@@ -37,24 +70,18 @@ module Bridgetown
37
70
  Bridgetown.logger.info "Environment:", Bridgetown.environment.cyan
38
71
  site = Bridgetown::Site.new(configuration_with_overrides(options))
39
72
 
40
- unless options[:blank]
41
- site.reset
42
- Bridgetown.logger.info "Reading files..."
43
- site.read
44
- Bridgetown.logger.info "", "done!"
45
- Bridgetown.logger.info "Running generators..."
46
- site.generate
47
- Bridgetown.logger.info "", "done!"
48
- end
73
+ ConsoleMethods.site_reset(site) unless options[:blank]
49
74
 
50
- $BRIDGETOWN_SITE = site
75
+ IRB::ExtendCommandBundle.include ConsoleMethods
51
76
  IRB.setup(nil)
52
77
  workspace = IRB::WorkSpace.new
53
78
  irb = IRB::Irb.new(workspace)
54
79
  IRB.conf[:IRB_RC]&.call(irb.context)
55
80
  IRB.conf[:MAIN_CONTEXT] = irb.context
56
- eval("site = $BRIDGETOWN_SITE", workspace.binding, __FILE__, __LINE__)
57
- Bridgetown.logger.info "Console:", "Now loaded as #{"site".cyan} variable."
81
+ Bridgetown.logger.info "Console:", "Your site is now available as #{"site".cyan}"
82
+ Bridgetown.logger.info "",
83
+ "You can also access #{"collections".cyan} or perform a" \
84
+ " #{"reload!".cyan}"
58
85
 
59
86
  trap("SIGINT") do
60
87
  irb.signal_handle
@@ -57,8 +57,7 @@ module Bridgetown
57
57
  def conflicting_urls(site)
58
58
  conflicting_urls = false
59
59
  urls = {}
60
- urls = collect_urls(urls, site.pages, site.dest)
61
- urls = collect_urls(urls, site.collections.posts.docs, site.dest)
60
+ urls = collect_urls(urls, site.contents, site.dest)
62
61
  urls.each do |url, paths|
63
62
  next unless paths.size > 1
64
63
 
@@ -98,7 +97,11 @@ module Bridgetown
98
97
 
99
98
  def collect_urls(urls, things, destination)
100
99
  things.each do |thing|
101
- dest = thing.destination(destination)
100
+ dest = if thing.method(:destination).arity == 1
101
+ thing.destination(destination)
102
+ else
103
+ thing.destination
104
+ end
102
105
  if urls[dest]
103
106
  urls[dest] << thing.path
104
107
  else
@@ -110,8 +113,8 @@ module Bridgetown
110
113
 
111
114
  def case_insensitive_urls(things, _destination)
112
115
  things.each_with_object({}) do |thing, memo|
113
- dest = thing.destination.output_path
114
- (memo[dest.downcase] ||= []) << dest
116
+ dest = thing.destination&.output_path
117
+ (memo[dest.downcase] ||= []) << dest if dest
115
118
  end
116
119
  end
117
120
 
@@ -187,7 +187,7 @@ module Bridgetown
187
187
  say_status "Done!", "Have fun writing your new #{name} plugin :)"
188
188
  say_status "Remember:", "Don't forget to rename the SamplePlugin" \
189
189
  " code identifiers and paths to your own" \
190
- " indentifer, as well as update your README " \
190
+ " indentifer, as well as update your README" \
191
191
  " and CHANGELOG files as necessary."
192
192
  end
193
193
 
@@ -56,5 +56,13 @@ class Bridgetown::Site
56
56
  c.new(config)
57
57
  end
58
58
  end
59
+
60
+ # Shorthand for registering a site hook via {Bridgetown::Hooks}
61
+ # @param event [Symbol] name of the event (`:pre_read`, `:post_render`, etc.)
62
+ # @yield the block will be called when the event is triggered
63
+ # @yieldparam site the site which triggered the event hook
64
+ def on(event, reloadable: false, &block)
65
+ Bridgetown::Hooks.register_one :site, event, reloadable: reloadable, &block
66
+ end
59
67
  end
60
68
  end
@@ -23,9 +23,9 @@ class Bridgetown::Site
23
23
 
24
24
  # Reset all in-memory data and content.
25
25
  #
26
-
26
+ # @param soft [Boolean] if true, persist some state and do a light refresh of layouts and data
27
27
  # @return [void]
28
- def reset(soft: false)
28
+ def reset(soft: false) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
29
29
  self.time = Time.now
30
30
  if config["time"]
31
31
  self.time = Bridgetown::Utils.parse_date(
@@ -41,12 +41,30 @@ class Bridgetown::Site
41
41
  @documents = nil
42
42
  @docs_to_write = nil
43
43
  @liquid_renderer.reset
44
- frontmatter_defaults.reset unless soft
45
44
 
46
- Bridgetown::Cache.clear_if_config_changed config unless soft
45
+ if soft
46
+ refresh_layouts_and_data
47
+ else
48
+ frontmatter_defaults.reset
49
+ Bridgetown::Cache.clear_if_config_changed config
50
+ end
51
+
47
52
  Bridgetown::Hooks.trigger :site, (soft ? :after_soft_reset : :after_reset), self
48
53
  end
49
54
 
55
+ # Read layouts and merge any new data collection contents into the site data
56
+ def refresh_layouts_and_data
57
+ reader.read_layouts
58
+
59
+ collections.data.tap do |coll|
60
+ coll.resources.clear
61
+ coll.read
62
+ coll.merge_data_resources.each do |k, v|
63
+ data[k] = v # refresh site data
64
+ end
65
+ end
66
+ end
67
+
50
68
  # Read data from disk and load it into internal memory.
51
69
  # @return [void]
52
70
  def read
@@ -32,7 +32,7 @@ class Bridgetown::Site
32
32
  @ssr_enabled = true
33
33
  end
34
34
 
35
- def ssr_setup(&block) # rubocop:disable Metrics/AbcSize
35
+ def ssr_setup
36
36
  config.serving = true
37
37
  Bridgetown::Hooks.trigger :site, :pre_read, self
38
38
  defaults_reader.tap do |d|
@@ -46,27 +46,12 @@ class Bridgetown::Site
46
46
  end
47
47
  Bridgetown::Hooks.trigger :site, :post_read, self
48
48
 
49
- hook = block&.(self) # provide additional setup hook
49
+ yield self if block_given? # provide additional setup hook
50
50
  return if Bridgetown.env.production?
51
51
 
52
- @ssr_reload_hook = hook if hook.is_a?(Proc) && hook.lambda?
53
52
  Bridgetown::Watcher.watch(self, config)
54
53
  end
55
54
 
56
- def ssr_reload
57
- reset soft: true
58
- reader.read_layouts
59
-
60
- collections.data.tap do |coll|
61
- coll.resources.clear
62
- coll.read
63
- coll.merge_data_resources.each do |k, v|
64
- data[k] = v
65
- end
66
- end
67
- @ssr_reload_hook.() if @ssr_reload_hook.is_a?(Proc)
68
- end
69
-
70
55
  def disable_ssr
71
56
  Bridgetown.logger.info "SSR:", "now disabled."
72
57
  @ssr_enabled = false
@@ -82,7 +82,7 @@ create_file "plugins/test_output.rb" do
82
82
  <<~RUBY
83
83
  module TestOutput
84
84
  unless Bridgetown.env.development?
85
- Bridgetown::Hooks.register :site, :post_write do
85
+ Bridgetown::Hooks.register_one :site, :post_write do
86
86
  # Load test suite to run on exit
87
87
  require "nokogiri"
88
88
  Dir["test/**/*.rb"].each { |file| require_relative("../\#{file}") }
@@ -5,6 +5,9 @@ services:
5
5
  buildCommand: bin/bridgetown deploy
6
6
  staticPublishPath: ./output
7
7
  pullRequestPreviewsEnabled: true
8
+ envVars:
9
+ - key: BRIDGETOWN_ENV
10
+ value: production
8
11
  headers:
9
12
  - path: /*
10
13
  name: X-Frame-Options
@@ -38,7 +38,7 @@ module Bridgetown
38
38
  return if text.empty?
39
39
 
40
40
  src << bufvar << ".safe_append='"
41
- src << text.gsub(%r{['\\]}, '\\\\\&') # rubocop:disable Style/StringLiterals
41
+ src << text.gsub(%r{['\\]}, '\\\\\&')
42
42
  src << "'.freeze;"
43
43
  end
44
44
 
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "serbea"
4
+ require "rouge/lexers/serbea"
5
+
6
+ module Bridgetown
7
+ class SerbeaView < ERBView
8
+ include Serbea::Helpers
9
+
10
+ def partial(partial_name, options = {}, &block)
11
+ options.merge!(options[:locals]) if options[:locals]
12
+ options[:content] = capture(&block) if block
13
+
14
+ partial_segments = partial_name.split("/")
15
+ partial_segments.last.sub!(%r!^!, "_")
16
+ partial_name = partial_segments.join("/")
17
+
18
+ Tilt::SerbeaTemplate.new(
19
+ site.in_source_dir(site.config[:partials_dir], "#{partial_name}.serb")
20
+ ).render(self, options)
21
+ end
22
+ end
23
+
24
+ module Converters
25
+ class SerbeaTemplates < Converter
26
+ priority :highest
27
+ input :serb
28
+
29
+ # Logic to do the Serbea content conversion.
30
+ #
31
+ # @param content [String] Content of the file (without front matter).
32
+ # @param convertible [
33
+ # Bridgetown::GeneratedPage, Bridgetown::Resource::Base, Bridgetown::Layout]
34
+ # The instantiated object which is processing the file.
35
+ #
36
+ # @return [String] The converted content.
37
+ def convert(content, convertible)
38
+ return content if convertible.data[:template_engine].to_s != "serbea"
39
+
40
+ serb_view = Bridgetown::SerbeaView.new(convertible)
41
+
42
+ serb_renderer = Tilt::SerbeaTemplate.new(convertible.relative_path) { content }
43
+
44
+ if convertible.is_a?(Bridgetown::Layout)
45
+ serb_renderer.render(serb_view) do
46
+ convertible.current_document_output
47
+ end
48
+ else
49
+ serb_renderer.render(serb_view)
50
+ end
51
+ end
52
+
53
+ def matches(ext, convertible)
54
+ if convertible.data[:template_engine].to_s == "serbea" ||
55
+ (convertible.data[:template_engine].nil? &&
56
+ @config[:template_engine].to_s == "serbea")
57
+ convertible.data[:template_engine] = "serbea"
58
+ return true
59
+ end
60
+
61
+ super(ext).tap do |ext_matches|
62
+ convertible.data[:template_engine] = "serbea" if ext_matches
63
+ end
64
+ end
65
+
66
+ def output_ext(ext)
67
+ ext == ".serb" ? ".html" : ext
68
+ end
69
+ end
70
+ end
71
+ end
@@ -110,7 +110,7 @@ module Bridgetown
110
110
  # underlying data hashes and performs a set union to ensure a list
111
111
  # of unique keys for the Drop.
112
112
  #
113
- # Returns an Array of unique keys for content for the Drop.
113
+ # @return [Array<String>]
114
114
  def keys
115
115
  (content_methods |
116
116
  mutations.keys |
@@ -6,7 +6,7 @@ module Bridgetown
6
6
  extend Forwardable
7
7
 
8
8
  NESTED_OBJECT_FIELD_BLACKLIST = %w(
9
- content output excerpt next previous
9
+ content output excerpt next previous next_resource previous_resource
10
10
  ).freeze
11
11
 
12
12
  mutable false
@@ -44,13 +44,15 @@ module Bridgetown
44
44
  cmp
45
45
  end
46
46
 
47
- def previous
48
- @previous ||= @obj.previous_resource.to_liquid
47
+ def next_resource
48
+ @next ||= @obj.next_resource.to_liquid
49
49
  end
50
+ alias_method :next, :next_resource
50
51
 
51
- def next
52
- @next ||= @obj.next_resource.to_liquid
52
+ def previous_resource
53
+ @previous ||= @obj.previous_resource.to_liquid
53
54
  end
55
+ alias_method :previous, :previous_resource
54
56
 
55
57
  # Generate a Hash for use in generating JSON.
56
58
  # This is useful if fields need to be cleared before the JSON can generate.
@@ -79,6 +81,27 @@ module Bridgetown
79
81
  result[key] = doc[key] unless NESTED_OBJECT_FIELD_BLACKLIST.include?(key)
80
82
  end
81
83
  end
84
+
85
+ # Generates a list of keys with user content as their values.
86
+ # This gathers up the Drop methods and keys of the mutations and
87
+ # underlying data hashes and performs a set union to ensure a list
88
+ # of unique keys for the Drop.
89
+ #
90
+ # @return [Array<String>]
91
+ def keys
92
+ keys_to_remove = %w[next_resource previous_resource]
93
+ (content_methods |
94
+ mutations.keys |
95
+ fallback_data.keys).flatten.reject do |key|
96
+ keys_to_remove.include?(key)
97
+ end
98
+ end
99
+
100
+ # Inspect the drop's keys and values through a JSON representation
101
+ # of its keys and values.
102
+ def inspect
103
+ JSON.pretty_generate hash_for_json
104
+ end
82
105
  end
83
106
  end
84
107
  end
@@ -1,21 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Handles Generated Pages
4
- Bridgetown::Hooks.register :generated_pages, :post_init, reloadable: false do |page|
4
+ Bridgetown::Hooks.register_one :generated_pages, :post_init, reloadable: false do |page|
5
5
  if page.class != Bridgetown::PrototypePage && page.data["prototype"].is_a?(Hash)
6
6
  Bridgetown::PrototypeGenerator.add_matching_template(page)
7
7
  end
8
8
  end
9
9
 
10
10
  # Handles Resources
11
- Bridgetown::Hooks.register :resources, :post_read, reloadable: false do |resource|
11
+ Bridgetown::Hooks.register_one :resources, :post_read, reloadable: false do |resource|
12
12
  if resource.data["prototype"].is_a?(Hash)
13
13
  Bridgetown::PrototypeGenerator.add_matching_template(resource)
14
14
  end
15
15
  end
16
16
 
17
17
  # Ensure sites clear out templates before rebuild
18
- Bridgetown::Hooks.register :site, :after_reset, reloadable: false do |_site|
18
+ Bridgetown::Hooks.register_one :site, :after_reset, reloadable: false do |_site|
19
19
  Bridgetown::PrototypeGenerator.matching_templates.clear
20
20
  end
21
21
 
@@ -17,34 +17,59 @@ module Bridgetown
17
17
 
18
18
  DEFAULT_PRIORITY = 20
19
19
 
20
- # compatibility layer for octopress-hooks users
21
20
  PRIORITY_MAP = {
22
21
  low: 10,
23
22
  normal: 20,
24
23
  high: 30,
25
24
  }.freeze
26
25
 
27
- # initial empty hooks
28
26
  @registry = {}
29
27
 
30
28
  NotAvailable = Class.new(RuntimeError)
31
29
  Uncallable = Class.new(RuntimeError)
32
30
 
33
- # Ensure the priority is a Fixnum
34
31
  def self.priority_value(priority)
35
32
  return priority if priority.is_a?(Integer)
36
33
 
37
34
  PRIORITY_MAP[priority] || DEFAULT_PRIORITY
38
35
  end
39
36
 
40
- # register hook(s) to be called later
37
+ # Sort registered hooks according to priority and load order
38
+ #
39
+ # @param hooks [Array<HookRegistration>]
40
+ def self.prioritized_hooks(hooks)
41
+ grouped_hooks = hooks.group_by(&:priority)
42
+ grouped_hooks.keys.sort.reverse.map { |priority| grouped_hooks[priority] }.flatten
43
+ end
44
+
45
+ # Register one or more hooks which may be triggered later for a particular event
46
+ #
47
+ # @param owners [Symbol, Array<Symbol>] name of the owner (`:site`, `:resource`, etc.)
48
+ # @param event [Symbol] name of the event (`:pre_read`, `:post_render`, etc.)
49
+ # @param priority [Integer, Symbol] either `:low`, `:normal`, or `:high`, or an integer.
50
+ # Default is normal (20)
51
+ # @param reloadable [Boolean] whether the hook should be removed prior to a site reload.
52
+ # Default is true.
53
+ # @yield the block will be called when the event is triggered. Typically it receives at
54
+ # least one argument.
55
+ # @yieldparam obj the object which triggered the event hook
41
56
  def self.register(owners, event, priority: DEFAULT_PRIORITY, reloadable: true, &block)
42
57
  Array(owners).each do |owner|
43
58
  register_one(owner, event, priority: priority, reloadable: reloadable, &block)
44
59
  end
45
60
  end
46
61
 
47
- # register a single hook to be called later
62
+ # Register a hook which may be triggered later for a particular event
63
+ #
64
+ # @param owner [Symbol] name of the owner (`:site`, `:resource`, etc.)
65
+ # @param event [Symbol] name of the event (`:pre_read`, `:post_render`, etc.)
66
+ # @param priority [Integer, Symbol] either `:low`, `:normal`, or `:high`, or an integer.
67
+ # Default is normal (20)
68
+ # @param reloadable [Boolean] whether the hook should be removed prior to a site reload.
69
+ # Default is true.
70
+ # @yield the block will be called when the event is triggered. Typically it receives at
71
+ # least one argument.
72
+ # @yieldparam obj the object which triggered the event hook
48
73
  def self.register_one(owner, event, priority: DEFAULT_PRIORITY, reloadable: true, &block)
49
74
  @registry[owner] ||= []
50
75
 
@@ -68,10 +93,28 @@ module Bridgetown
68
93
  block
69
94
  end
70
95
 
71
- def self.remove_hook(owner, _event, block)
96
+ # Delete a previously-registered hook
97
+ #
98
+ # @param owners [Symbol] name of the owner (`:site`, `:resource`, etc.)
99
+ # @param block [Proc] the exact block used originally to register the hook
100
+ def self.remove_hook(owner, block)
72
101
  @registry[owner].delete_if { |item| item.block == block }
73
102
  end
74
103
 
104
+ # Clear all hooks marked as reloadable from the registry
105
+ def self.clear_reloadable_hooks
106
+ Bridgetown.logger.debug("Clearing reloadable hooks")
107
+
108
+ @registry.each_value do |hooks|
109
+ hooks.delete_if(&:reloadable)
110
+ end
111
+ end
112
+
113
+ # Trigger all registered hooks for a particular owner and event.
114
+ # Any arguments after the initial two will be directly passed along to the hooks.
115
+ #
116
+ # @param owner [Symbol] name of the owner (`:site`, `:resource`, etc.)
117
+ # @param event [Symbol] name of the event (`:pre_read`, `:post_render`, etc.)
75
118
  def self.trigger(owner, event, *args) # rubocop:disable Metrics/CyclomaticComplexity
76
119
  # proceed only if there are hooks to call
77
120
  hooks = @registry[owner]&.select { |item| item.event == event }
@@ -79,25 +122,13 @@ module Bridgetown
79
122
 
80
123
  prioritized_hooks(hooks).each do |hook|
81
124
  if ENV["BRIDGETOWN_LOG_LEVEL"] == "debug"
82
- hook_info = args[0].respond_to?(:url) ? args[0].relative_path : hook.block
125
+ hook_info = args[0].respond_to?(:relative_path) ? args[0].relative_path : hook.block
83
126
  Bridgetown.logger.debug("Triggering hook:", "#{owner}:#{event} for #{hook_info}")
84
127
  end
85
128
  hook.block.call(*args)
86
129
  end
87
- end
88
-
89
- def self.prioritized_hooks(hooks)
90
- # sort hooks according to priority and load order
91
- grouped_hooks = hooks.group_by(&:priority)
92
- grouped_hooks.keys.sort.reverse.map { |priority| grouped_hooks[priority] }.flatten
93
- end
94
130
 
95
- def self.clear_reloadable_hooks
96
- Bridgetown.logger.debug("Clearing reloadable hooks")
97
-
98
- @registry.each_value do |hooks|
99
- hooks.delete_if(&:reloadable)
100
- end
131
+ true
101
132
  end
102
133
  end
103
134
  end
@@ -31,9 +31,7 @@ module Bridgetown
31
31
  raise Liquid::FileSystemError, "No such template '#{template_path}'" if found_paths.empty?
32
32
 
33
33
  # Last path in the list wins
34
- LiquidComponent.parse(
35
- ::File.read(found_paths.last, **site.file_read_opts)
36
- ).content
34
+ ::File.read(found_paths.last, **site.file_read_opts)
37
35
  end
38
36
  end
39
37
  end
@@ -69,8 +69,23 @@ module Bridgetown
69
69
  attributes[:_origin_]
70
70
  end
71
71
 
72
+ def origin=(new_origin)
73
+ attributes[:_id_] = new_origin.id
74
+ attributes[:_origin_] = new_origin
75
+ end
76
+
72
77
  def persisted?
73
- id && origin.exists?
78
+ (id && origin&.exists?) == true
79
+ end
80
+
81
+ def save
82
+ unless origin.respond_to?(:write)
83
+ raise "`#{origin.class}' doesn't allow writing of model objects"
84
+ end
85
+
86
+ run_callbacks :save do
87
+ origin.write(self)
88
+ end
74
89
  end
75
90
 
76
91
  # @return [Bridgetown::Resource::Base]
@@ -100,11 +115,19 @@ module Bridgetown
100
115
  attributes[:_collection_]
101
116
  end
102
117
 
118
+ def collection=(new_collection)
119
+ attributes[:_collection_] = new_collection
120
+ end
121
+
103
122
  # @return [String]
104
123
  def content
105
124
  attributes[:_content_]
106
125
  end
107
126
 
127
+ def content=(new_content)
128
+ attributes[:_content_] = new_content
129
+ end
130
+
108
131
  def attributes
109
132
  @attributes ||= HashWithDotAccess::Hash.new
110
133
  end
@@ -25,6 +25,18 @@ module Bridgetown
25
25
  def data_file_extensions
26
26
  %w(.yaml .yml .json .csv .tsv .rb).freeze
27
27
  end
28
+
29
+ # Initializes a new repo object using a collection and a relative source path.
30
+ # You'll need to use this when you want to create and save a model to the source.
31
+ #
32
+ # @param collection [Bridgetown::Collection, String, Symbol] either a collection
33
+ # label or Collection object
34
+ # @param relative_path [Pathname, String] the source path of the file to save
35
+ def new_with_collection_path(collection, relative_path)
36
+ collection = collection.label if collection.is_a?(Bridgetown::Collection)
37
+
38
+ new("repo://#{collection}.collection/#{relative_path}")
39
+ end
28
40
  end
29
41
 
30
42
  def read
@@ -46,6 +58,23 @@ module Bridgetown
46
58
  @data
47
59
  end
48
60
 
61
+ def write(model)
62
+ if File.exist?(original_path) && !Bridgetown::Utils.has_yaml_header?(original_path)
63
+ raise Bridgetown::Errors::InvalidYAMLFrontMatterError,
64
+ "Only existing files containing YAML front matter can be overwritten by the model"
65
+ end
66
+
67
+ contents = "#{front_matter_to_yaml(model)}---\n\n#{model.content}"
68
+
69
+ # Create folders if necessary
70
+ dir = File.dirname(original_path)
71
+ FileUtils.mkdir_p(dir) unless File.directory?(dir)
72
+
73
+ File.write(original_path, contents)
74
+
75
+ true
76
+ end
77
+
49
78
  def url
50
79
  @url ||= URI.parse(id)
51
80
  end
@@ -121,6 +150,25 @@ module Bridgetown
121
150
  raise error
122
151
  end
123
152
  end
153
+
154
+ def front_matter_to_yaml(model)
155
+ data = model.data_attributes.to_h
156
+ data = data.deep_merge(data) do |_, _, v|
157
+ case v
158
+ when DateTime
159
+ v.to_time
160
+ when Symbol
161
+ v.to_s
162
+ else
163
+ v
164
+ end
165
+ end
166
+ data.each do |k, v|
167
+ data.delete(k) if v.nil?
168
+ end
169
+
170
+ data.to_yaml
171
+ end
124
172
  end
125
173
  end
126
174
  end
@@ -18,8 +18,8 @@ module Bridgetown
18
18
  @source_manifests << source_manifest
19
19
  end
20
20
 
21
- def self.new_source_manifest(*args)
22
- add_source_manifest(Bridgetown::Plugin::SourceManifest.new(*args))
21
+ def self.new_source_manifest(*args, **kwargs)
22
+ add_source_manifest(Bridgetown::Plugin::SourceManifest.new(*args, **kwargs))
23
23
  end
24
24
 
25
25
  def self.add_registered_plugin(gem_or_plugin_file)
@@ -23,6 +23,7 @@ module Bridgetown
23
23
  plugin :json
24
24
  plugin :json_parser
25
25
  plugin :cookies
26
+ plugin :streaming
26
27
  plugin :public, root: Bridgetown::Current.preloaded_configuration.destination
27
28
  plugin :not_found do
28
29
  output_folder = Bridgetown::Current.preloaded_configuration.destination
@@ -39,7 +40,7 @@ module Bridgetown
39
40
  "500 Internal Server Error"
40
41
  end
41
42
 
42
- def _roda_run_main_route(r) # rubocop:disable Naming/MethodParameterName
43
+ before do
43
44
  if self.class.opts[:bridgetown_site]
44
45
  # The site had previously been initialized via the bridgetown_ssr plugin
45
46
  Bridgetown::Current.site ||= self.class.opts[:bridgetown_site]
@@ -47,14 +48,12 @@ module Bridgetown
47
48
  Bridgetown::Current.preloaded_configuration ||=
48
49
  self.class.opts[:bridgetown_preloaded_config]
49
50
 
50
- r.public
51
+ request.public
51
52
 
52
- r.root do
53
+ request.root do
53
54
  output_folder = Bridgetown::Current.preloaded_configuration.destination
54
55
  File.read(File.join(output_folder, "index.html"))
55
56
  end
56
-
57
- super
58
57
  end
59
58
 
60
59
  # Helper shorthand for Bridgetown::Current.site
@@ -2,6 +2,12 @@
2
2
 
3
3
  module Bridgetown
4
4
  module Rack
5
+ @interrupted = false
6
+
7
+ class << self
8
+ attr_accessor :interrupted
9
+ end
10
+
5
11
  class Routes
6
12
  class << self
7
13
  attr_accessor :tracked_subclasses, :router_block
@@ -37,7 +43,7 @@ module Bridgetown
37
43
  def start!(roda_app)
38
44
  if Bridgetown.env.development? &&
39
45
  !Bridgetown::Current.preloaded_configuration.skip_live_reload
40
- setup_live_reload roda_app.request
46
+ setup_live_reload roda_app
41
47
  end
42
48
 
43
49
  Bridgetown::Rack::Routes.tracked_subclasses&.each_value do |klass|
@@ -51,15 +57,31 @@ module Bridgetown
51
57
  nil
52
58
  end
53
59
 
54
- def setup_live_reload(request)
55
- request.get "_bridgetown/live_reload" do
56
- {
57
- last_mod: File.stat(
58
- File.join(Bridgetown::Current.preloaded_configuration.destination, "index.html")
59
- ).mtime.to_i,
60
- }
61
- rescue StandardError => e
62
- { last_mod: 0, error: e.message }
60
+ def setup_live_reload(app) # rubocop:disable Metrics/AbcSize
61
+ sleep_interval = 0.2
62
+ file_to_check = File.join(app.class.opts[:bridgetown_preloaded_config].destination,
63
+ "index.html")
64
+
65
+ app.request.get "_bridgetown/live_reload" do
66
+ app.response["Content-Type"] = "text/event-stream"
67
+
68
+ @_mod = File.exist?(file_to_check) ? File.stat(file_to_check).mtime.to_i : 0
69
+ app.stream async: true do |out|
70
+ # 5 second intervals so Puma's threads aren't all exausted
71
+ (5 / sleep_interval).to_i.times do
72
+ break if Bridgetown::Rack.interrupted
73
+
74
+ new_mod = File.exist?(file_to_check) ? File.stat(file_to_check).mtime.to_i : 0
75
+ if @_mod < new_mod
76
+ out << "data: reloaded!\n\n"
77
+ break
78
+ else
79
+ out << "data: #{new_mod}\n\n"
80
+ end
81
+
82
+ sleep sleep_interval
83
+ end
84
+ end
63
85
  end
64
86
  end
65
87
  end
@@ -86,3 +108,15 @@ module Bridgetown
86
108
  end
87
109
  end
88
110
  end
111
+
112
+ if Bridgetown.env.development? &&
113
+ !Bridgetown::Current.preloaded_configuration.skip_live_reload
114
+ Puma::Launcher.class_eval do
115
+ alias_method :_old_stop, :stop
116
+ def stop
117
+ Bridgetown::Rack.interrupted = true
118
+
119
+ _old_stop
120
+ end
121
+ end
122
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "roda/plugins/public"
4
4
 
5
+ # NOTE: once this upstreamed PR is merged in we can remove this file.
6
+ # https://github.com/jeremyevans/roda/pull/215
5
7
  Roda::RodaPlugins::Public::RequestMethods.module_eval do
6
8
  SPLIT = Regexp.union(*[File::SEPARATOR, File::ALT_SEPARATOR].compact) # rubocop:disable Lint/ConstantDefinitionInBlock
7
9
  def public_path_segments(path) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
@@ -284,12 +284,14 @@ module Bridgetown
284
284
  collection.resources[pos + 1] if pos && pos < collection.resources.length - 1
285
285
  end
286
286
  alias_method :next_doc, :next_resource
287
+ alias_method :next, :next_resource
287
288
 
288
289
  def previous_resource
289
290
  pos = collection.resources.index { |item| item.equal?(self) }
290
291
  collection.resources[pos - 1] if pos&.positive?
291
292
  end
292
293
  alias_method :previous_doc, :previous_resource
294
+ alias_method :previous, :previous_resource
293
295
 
294
296
  private
295
297
 
@@ -28,6 +28,16 @@ module Bridgetown
28
28
  load_path.start_with?(root_dir) && ENV["BRIDGETOWN_ENV"] != "production"
29
29
  end
30
30
 
31
+ def clear_descendants_for_reload(_cpath, value, _abspath)
32
+ unless value.is_a?(Class) && value.singleton_class < ActiveSupport::DescendantsTracker
33
+ return
34
+ end
35
+
36
+ ActiveSupport::DescendantsTracker.class_variable_get(
37
+ :@@direct_descendants
38
+ )[value.superclass]&.reject! { _1 == value }
39
+ end
40
+
31
41
  def setup_loaders(autoload_paths = []) # rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
32
42
  (autoload_paths.presence || config.autoload_paths).each do |load_path|
33
43
  if @loaders.key?(load_path)
@@ -49,6 +59,7 @@ module Bridgetown
49
59
 
50
60
  loader.collapse(collapsed_path)
51
61
  end
62
+ loader.on_unload(&method(:clear_descendants_for_reload)) # rubocop:disable Performance/MethodObjectAsBlock
52
63
  Bridgetown::Hooks.trigger :loader, :pre_setup, loader, load_path
53
64
  loader.setup
54
65
  loader.eager_load if config.eager_load_paths.include?(load_path)
@@ -401,30 +401,34 @@ module Bridgetown
401
401
  return "" unless Bridgetown.env.development? && !site.config.skip_live_reload
402
402
 
403
403
  code = <<~JAVASCRIPT
404
- let first_mod = 0
405
- let connection_errors = 0
406
- const checkForReload = () => {
407
- fetch("/_bridgetown/live_reload").then(response => {
408
- if (response.ok) {
409
- response.json().then(data => {
410
- const last_mod = data.last_mod
411
- if (first_mod === 0) {
412
- first_mod = last_mod
413
- } else if (last_mod > first_mod) {
414
- location.reload()
415
- }
416
- setTimeout(() => checkForReload(), 700)
417
- })
404
+ let lastmod = 0
405
+ function startReloadConnection() {
406
+ const evtSource = new EventSource("/_bridgetown/live_reload")
407
+ evtSource.onmessage = event => {
408
+ if (event.data == "reloaded!") {
409
+ location.reload()
418
410
  } else {
419
- if (connection_errors < 20) setTimeout(() => checkForReload(), 6000)
420
- connection_errors++
411
+ const newmod = Number(event.data)
412
+ if (lastmod > 0 && newmod > 0 && lastmod < newmod) {
413
+ location.reload()
414
+ } else {
415
+ lastmod = newmod
416
+ }
421
417
  }
422
- }).catch((err) => {
423
- if (connection_errors < 20) setTimeout(() => checkForReload(), 6000)
424
- connection_errors++
425
- })
418
+ }
419
+ evtSource.onerror = event => {
420
+ if (evtSource.readyState === 2) {
421
+ // reconnect with new object
422
+ evtSource.close()
423
+ console.warn("Live reload: attempting to reconnect in 3 seconds...")
424
+
425
+ setTimeout(() => startReloadConnection(), 3000)
426
+ }
427
+ }
426
428
  }
427
- checkForReload()
429
+ setTimeout(() => {
430
+ startReloadConnection()
431
+ }, 500)
428
432
  JAVASCRIPT
429
433
 
430
434
  %(<script type="module">#{code}</script>).html_safe
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- VERSION = "1.0.0.alpha7"
4
+ VERSION = "1.0.0.alpha11"
5
5
  CODE_NAME = "Pearl"
6
6
  end
@@ -4,71 +4,102 @@ module Bridgetown
4
4
  module Watcher
5
5
  extend self
6
6
 
7
- # Public: Continuously watch for file changes and rebuild the site
8
- # whenever a change is detected.
7
+ # Continuously watch for file changes and rebuild the site whenever a change is detected.
9
8
  #
10
- # site - The current site instance
11
- # options - A Hash containing the site configuration
12
- #
13
- # Returns nothing.
9
+ # @param site [Bridgetown::Site] the current site instance
10
+ # @param options [Bridgetown::Configuration] the site configuration
14
11
  def watch(site, options)
15
12
  ENV["LISTEN_GEM_DEBUGGING"] ||= "1" if options["verbose"]
16
13
 
17
- listener = build_listener(site, options)
18
- listener.start
14
+ listen(site, options)
19
15
 
20
- Bridgetown.logger.info "Auto-regeneration:", "enabled." unless options[:using_puma]
16
+ Bridgetown.logger.info "Watcher:", "enabled." unless options[:using_puma]
21
17
 
22
18
  unless options[:serving]
23
19
  trap("INT") do
24
- listener.stop
25
- Bridgetown.logger.info "", "Halting auto-regeneration."
26
20
  exit 0
27
21
  end
28
22
 
29
23
  sleep_forever
30
24
  end
31
25
  rescue ThreadError
32
- # You pressed Ctrl-C, oh my!
26
+ # NOTE: not sure if this is needed any longer
33
27
  end
34
28
 
35
- private
29
+ # Return a list of load paths which should be watched for changes
30
+ #
31
+ # @param (see #watch)
32
+ def load_paths_to_watch(site, options)
33
+ site.plugin_manager.plugins_path.select { |path| Dir.exist?(path) }
34
+ .then do |paths|
35
+ (paths + options.autoload_paths).uniq
36
+ end
37
+ end
36
38
 
37
- def build_listener(site, options)
39
+ # Start a listener to watch for changes and call {#reload_site}
40
+ #
41
+ # @param (see #watch)
42
+ def listen(site, options)
38
43
  webpack_path = site.in_root_dir(".bridgetown-webpack")
39
44
  FileUtils.mkdir(webpack_path) unless Dir.exist?(webpack_path)
40
- plugin_paths_to_watch = site.plugin_manager.plugins_path.select do |path|
41
- Dir.exist?(path)
42
- end
43
-
44
- paths_to_watch = (plugin_paths_to_watch + options.autoload_paths).uniq
45
-
46
45
  Listen.to(
47
46
  options["source"],
48
47
  webpack_path,
49
- *paths_to_watch,
48
+ *load_paths_to_watch(site, options),
50
49
  ignore: listen_ignore_paths(options),
51
- force_polling: options["force_polling"],
52
- &listen_handler(site, options)
53
- )
54
- end
55
-
56
- def listen_handler(site, options)
57
- proc do |modified, added, removed|
58
- t = Time.now
50
+ force_polling: options["force_polling"]
51
+ ) do |modified, added, removed|
59
52
  c = modified + added + removed
60
53
  n = c.length
61
54
 
62
55
  unless site.ssr?
63
- Bridgetown.logger.info "Regenerating…"
64
- Bridgetown.logger.info "", "#{n} file(s) changed at #{t.strftime("%Y-%m-%d %H:%M:%S")}"
65
- c.each { |path| Bridgetown.logger.info "", path["#{site.root_dir}/".length..] }
56
+ Bridgetown.logger.info(
57
+ "Reloading…",
58
+ "#{n} file#{"s" if c.length > 1} changed at #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}"
59
+ )
60
+ c.each { |path| Bridgetown.logger.info "", "- #{path["#{site.root_dir}/".length..]}" }
66
61
  end
67
62
 
68
- process(site, t, options)
63
+ reload_site(site, options)
64
+ end.start
65
+ end
66
+
67
+ # Reload the site including plugins and Zeitwerk autoloaders and process it (unless SSR)
68
+ #
69
+ # @param (see #watch)
70
+ def reload_site(site, options) # rubocop:todo Metrics/MethodLength
71
+ begin
72
+ time = Time.now
73
+ I18n.reload! # make sure any locale files get read again
74
+ Bridgetown::Current.site = site # needed in SSR mode apparently
75
+ Bridgetown::Hooks.trigger :site, :pre_reload, site
76
+ Bridgetown::Hooks.clear_reloadable_hooks
77
+ site.plugin_manager.reload_plugin_files
78
+ site.loaders_manager.reload_loaders
79
+ Bridgetown::Hooks.trigger :site, :post_reload, site
80
+
81
+ if site.ssr?
82
+ site.reset(soft: true)
83
+ return
84
+ end
85
+
86
+ site.process
87
+ Bridgetown.logger.info "Done! 🎉", "#{"Completed".green} in less than" \
88
+ " #{(Time.now - time).ceil(2)} seconds."
89
+ rescue Exception => e
90
+ Bridgetown.logger.error "Error:", e.message
91
+
92
+ if options[:trace]
93
+ Bridgetown.logger.info e.backtrace.join("\n")
94
+ else
95
+ Bridgetown.logger.warn "Backtrace:", "Use the --trace option for more information."
96
+ end
69
97
  end
98
+ Bridgetown.logger.info ""
70
99
  end
71
100
 
101
+ private
102
+
72
103
  def normalize_encoding(obj, desired_encoding)
73
104
  case obj
74
105
  when Array
@@ -126,32 +157,5 @@ module Bridgetown
126
157
  def sleep_forever
127
158
  loop { sleep 1000 }
128
159
  end
129
-
130
- # @param site [Bridgetown::Site]
131
- def process(site, time, options)
132
- begin
133
- I18n.reload! # make sure any locale files get read again
134
- Bridgetown::Current.site = site # needed in SSR mode apparently
135
- Bridgetown::Hooks.trigger :site, :pre_reload, site
136
- Bridgetown::Hooks.clear_reloadable_hooks
137
- site.plugin_manager.reload_plugin_files
138
- site.loaders_manager.reload_loaders
139
-
140
- return site.ssr_reload if site.ssr?
141
-
142
- site.process
143
- Bridgetown.logger.info "Done! 🎉", "#{"Completed".green} in less than" \
144
- " #{(Time.now - time).ceil(2)} seconds."
145
- rescue Exception => e
146
- Bridgetown.logger.error "Error:", e.message
147
-
148
- if options[:trace]
149
- Bridgetown.logger.info e.backtrace.join("\n")
150
- else
151
- Bridgetown.logger.warn "Backtrace:", "Use the --trace option for more information."
152
- end
153
- end
154
- Bridgetown.logger.info ""
155
- end
156
160
  end
157
161
  end
@@ -46,7 +46,6 @@ require "active_support/descendants_tracker"
46
46
  require "hash_with_dot_access"
47
47
  require "addressable/uri"
48
48
  require "liquid"
49
- require "liquid-component"
50
49
  require "listen"
51
50
  require "kramdown"
52
51
  require "colorator"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridgetown-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha7
4
+ version: 1.0.0.alpha11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bridgetown Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-05 00:00:00.000000000 Z
11
+ date: 2021-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -192,20 +192,6 @@ dependencies:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
194
  version: '5.0'
195
- - !ruby/object:Gem::Dependency
196
- name: liquid-component
197
- requirement: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - ">="
200
- - !ruby/object:Gem::Version
201
- version: '0.1'
202
- type: :runtime
203
- prerelease: false
204
- version_requirements: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - ">="
207
- - !ruby/object:Gem::Version
208
- version: '0.1'
209
195
  - !ruby/object:Gem::Dependency
210
196
  name: listen
211
197
  requirement: !ruby/object:Gem::Requirement
@@ -276,6 +262,20 @@ dependencies:
276
262
  - - "~>"
277
263
  - !ruby/object:Gem::Version
278
264
  version: '3.0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: serbea
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - "~>"
270
+ - !ruby/object:Gem::Version
271
+ version: '1.0'
272
+ type: :runtime
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - "~>"
277
+ - !ruby/object:Gem::Version
278
+ version: '1.0'
279
279
  - !ruby/object:Gem::Dependency
280
280
  name: terminal-table
281
281
  requirement: !ruby/object:Gem::Requirement
@@ -332,6 +332,20 @@ dependencies:
332
332
  - - "~>"
333
333
  - !ruby/object:Gem::Version
334
334
  version: '1.7'
335
+ - !ruby/object:Gem::Dependency
336
+ name: zeitwerk
337
+ requirement: !ruby/object:Gem::Requirement
338
+ requirements:
339
+ - - "~>"
340
+ - !ruby/object:Gem::Version
341
+ version: '2.5'
342
+ type: :runtime
343
+ prerelease: false
344
+ version_requirements: !ruby/object:Gem::Requirement
345
+ requirements:
346
+ - - "~>"
347
+ - !ruby/object:Gem::Version
348
+ version: '2.5'
335
349
  description: Bridgetown is a Webpack-aware, Ruby-powered static site generator for
336
350
  the modern Jamstack era
337
351
  email: maintainers@bridgetownrb.com
@@ -418,6 +432,7 @@ files:
418
432
  - lib/bridgetown-core/converters/markdown.rb
419
433
  - lib/bridgetown-core/converters/markdown/kramdown_parser.rb
420
434
  - lib/bridgetown-core/converters/ruby_templates.rb
435
+ - lib/bridgetown-core/converters/serbea_templates.rb
421
436
  - lib/bridgetown-core/converters/smartypants.rb
422
437
  - lib/bridgetown-core/core_ext/psych.rb
423
438
  - lib/bridgetown-core/current.rb