Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Zeitwerk for autoload/eager load paths (including plugins) #434

Merged
merged 12 commits into from
Nov 5, 2021
Merged
1 change: 1 addition & 0 deletions bridgetown-builder/test/test_generators.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class TestGenerators < BridgetownUnitTest
should "be loaded on site setup" do
@site.reset
@site.data[:site_metadata] = { title: "Initial Value" }
@site.loaders_manager.unload_loaders
@site.setup
@site.generate

Expand Down
2 changes: 2 additions & 0 deletions bridgetown-builder/test/test_hooks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class TestHooks < BridgetownUnitTest

should "be triggered" do
@site.reset
@site.loaders_manager.unload_loaders
@site.setup
Bridgetown::Hooks.trigger :site, :pre_read, @site

Expand Down Expand Up @@ -69,6 +70,7 @@ class TestHooks < BridgetownUnitTest

should "be loaded" do
@site.reset
@site.loaders_manager.unload_loaders
@site.setup
Bridgetown::Hooks.trigger :site, :pre_read, @site

Expand Down
1 change: 1 addition & 0 deletions bridgetown-builder/test/test_method_symbols.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class TestMethodSymbols < BridgetownUnitTest
should "load generator on site generate" do
@site.reset
@site.data[:site_metadata] = { title: "Initial Value in Method Symbols" }
@site.loaders_manager.unload_loaders
@site.setup

assert_equal "Initial Value in Method Symbols", @site.metadata[:title]
Expand Down
136 changes: 82 additions & 54 deletions bridgetown-core/features/hooks.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ Feature: Hooks
Given I have a plugins directory
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register :site, :after_reset do |site|
pg = Bridgetown::GeneratedPage.new(site, site.source, "/", "foo.html")
pg.content = "mytinypage"
module Ext
Bridgetown::Hooks.register :site, :after_reset do |site|
pg = Bridgetown::GeneratedPage.new(site, site.source, "/", "foo.html")
pg.content = "mytinypage"

site.generated_pages << pg
site.generated_pages << pg
end
end
"""
When I run bridgetown build
Expand All @@ -24,8 +26,10 @@ Feature: Hooks
And I have a "page2.html" page that contains "page2"
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register :site, :post_read do |site|
site.collections.pages.resources.delete_if { |p| p.relative_path.basename.to_s == 'page1.html' }
module Ext
Bridgetown::Hooks.register :site, :post_read do |site|
site.collections.pages.resources.delete_if { |p| p.relative_path.basename.to_s == 'page1.html' }
end
end
"""
When I run bridgetown build
Expand All @@ -38,10 +42,12 @@ Feature: Hooks
Given I have a plugins directory
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register :site, :post_write do |site|
firstpage = site.collections.pages.resources.first
content = File.read firstpage.destination.output_path
File.write(File.join(site.dest, 'firstpage.html'), content)
module Ext
Bridgetown::Hooks.register :site, :post_write do |site|
firstpage = site.collections.pages.resources.first
content = File.read firstpage.destination.output_path
File.write(File.join(site.dest, 'firstpage.html'), content)
end
end
"""
And I have a "page1.html" page that contains "page1"
Expand All @@ -55,8 +61,10 @@ Feature: Hooks
And I have a "index.html" page that contains "WRAP ME"
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register :pages, :post_render do |page|
page.output = "{{{{{ #{page.output.chomp} }}}}}"
module Ext
Bridgetown::Hooks.register :pages, :post_render do |page|
page.output = "{{{{{ #{page.output.chomp} }}}}}"
end
end
"""
When I run bridgetown build
Expand All @@ -67,10 +75,12 @@ Feature: Hooks
And I have a "index.html" page that contains "HELLO FROM A PAGE"
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register :pages, :post_write do |page|
require 'fileutils'
filename = page.destination.output_path
FileUtils.mv(filename, "#{filename}.moved")
module Ext
Bridgetown::Hooks.register :pages, :post_write do |page|
require 'fileutils'
filename = page.destination.output_path
FileUtils.mv(filename, "#{filename}.moved")
end
end
"""
When I run bridgetown build
Expand All @@ -80,9 +90,11 @@ Feature: Hooks
Given I have a plugins directory
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register :posts, :post_init do |post|
post.data['harold'] = "content for entry1.".tr!('abcdefghijklmnopqrstuvwxyz',
'nopqrstuvwxyzabcdefghijklm')
module Ext
Bridgetown::Hooks.register :posts, :post_init do |post|
post.data['harold'] = "content for entry1.".tr!('abcdefghijklmnopqrstuvwxyz',
'nopqrstuvwxyzabcdefghijklm')
end
end
"""
And I have a _posts directory
Expand All @@ -100,11 +112,13 @@ Feature: Hooks
"""
# Add myvar = 'old' to posts before 2015-03-15, and myvar = 'new' for
# others
Bridgetown::Hooks.register :posts, :pre_render do |post|
if post.date < Time.new(2015, 3, 15)
post.data.myvar = 'old'
else
post.data.myvar = 'new'
module Ext
Bridgetown::Hooks.register :posts, :pre_render do |post|
if post.date < Time.new(2015, 3, 15)
post.data.myvar = 'old'
else
post.data.myvar = 'new'
end
end
end
"""
Expand All @@ -122,8 +136,10 @@ Feature: Hooks
And I have a "plugins/ext.rb" file with content:
"""
# Replace content after rendering
Bridgetown::Hooks.register :posts, :post_render do |post|
post.output.gsub! /42/, 'the answer to life, the universe and everything'
module Ext
Bridgetown::Hooks.register :posts, :post_render do |post|
post.output.gsub! /42/, 'the answer to life, the universe and everything'
end
end
"""
And I have a _posts directory
Expand All @@ -140,10 +156,12 @@ Feature: Hooks
And I have a "plugins/ext.rb" file with content:
"""
# Log all post filesystem writes
Bridgetown::Hooks.register :posts, :post_write do |post|
filename = post.destination.output_path
open('output/post-build.log', 'a') do |f|
f.puts "Wrote #{filename} at #{Time.now}"
module Ext
Bridgetown::Hooks.register :posts, :post_write do |post|
filename = post.destination.output_path
open('output/post-build.log', 'a') do |f|
f.puts "Wrote #{filename} at #{Time.now}"
end
end
end
"""
Expand All @@ -160,8 +178,10 @@ Feature: Hooks
Given I have a plugins directory
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register [:pages, :posts], :post_render do |owner|
owner.output = "{{{{{ #{owner.output.chomp} }}}}}"
module Ext
Bridgetown::Hooks.register [:pages, :posts], :post_render do |owner|
owner.output = "{{{{{ #{owner.output.chomp} }}}}}"
end
end
"""
And I have a "index.html" page that contains "WRAP ME"
Expand All @@ -177,21 +197,23 @@ Feature: Hooks
Given I have a plugins directory
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register :pages, :post_render, priority: :normal do |owner|
# first normal runs second
owner.output = "1 #{owner.output.chomp}"
end
Bridgetown::Hooks.register :pages, :post_render, priority: :high do |owner|
# high runs first
owner.output = "2 #{owner.output.chomp}"
end
Bridgetown::Hooks.register :pages, :post_render do |owner|
# second normal runs third (normal is default)
owner.output = "3 #{owner.output.chomp}"
end
Bridgetown::Hooks.register :pages, :post_render, priority: :low do |owner|
# low runs last
owner.output = "4 #{owner.output.chomp}"
module Ext
Bridgetown::Hooks.register :pages, :post_render, priority: :normal do |owner|
# first normal runs second
owner.output = "1 #{owner.output.chomp}"
end
Bridgetown::Hooks.register :pages, :post_render, priority: :high do |owner|
# high runs first
owner.output = "2 #{owner.output.chomp}"
end
Bridgetown::Hooks.register :pages, :post_render do |owner|
# second normal runs third (normal is default)
owner.output = "3 #{owner.output.chomp}"
end
Bridgetown::Hooks.register :pages, :post_render, priority: :low do |owner|
# low runs last
owner.output = "4 #{owner.output.chomp}"
end
end
"""
And I have a "index.html" page that contains "WRAP ME"
Expand All @@ -202,8 +224,10 @@ Feature: Hooks
Given I have a plugins directory
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register :resources, :pre_render do |doc, payload|
doc.data['text'] = doc.data['text'] << ' are belong to us' if doc.data['text']
module Ext
Bridgetown::Hooks.register :resources, :pre_render do |doc, payload|
doc.data['text'] = doc.data['text'] << ' are belong to us' if doc.data['text']
end
end
"""
And I have a "bridgetown.config.yml" file that contains "collections: [ memes ]"
Expand All @@ -229,8 +253,10 @@ Feature: Hooks
Given I have a plugins directory
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register :resources, :post_render do |doc|
doc.output.gsub! /<p>/, '<p class="meme">'
module Ext
Bridgetown::Hooks.register :resources, :post_render do |doc|
doc.output.gsub! /<p>/, '<p class="meme">'
end
end
"""
And I have a "bridgetown.config.yml" file with content:
Expand All @@ -256,9 +282,11 @@ Feature: Hooks
Given I have a plugins directory
And I have a "plugins/ext.rb" file with content:
"""
Bridgetown::Hooks.register :resources, :post_write do |doc|
open('output/document-build.log', 'a') do |f|
f.puts "Wrote document #{doc.collection.resources.index doc} at #{Time.now}"
module Ext
Bridgetown::Hooks.register :resources, :post_write do |doc|
open('output/document-build.log', 'a') do |f|
f.puts "Wrote document #{doc.collection.resources.index doc} at #{Time.now}"
end
end
end
"""
Expand Down
46 changes: 46 additions & 0 deletions bridgetown-core/features/site_configuration.feature
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,49 @@ Feature: Site configuration
And the output directory should exist
And I should see "FOO" in "output/index.html"
And I should not see " " in "output/index.html"

Scenario: Allow collapsed Zeitwerk dirs with specific dir name
Given I have a "plugins/nested" directory
And I have a "plugins/nested/top_level.rb" file with content:
"""
module TopLevel
Bridgetown::Hooks.register :site, :after_reset do |site|
pg = Bridgetown::GeneratedPage.new(site, site.source, "/", "foo.html")
pg.content = "Zeitwerk specific dir"

site.generated_pages << pg
end
end
"""
And I have a "bridgetown.config.yml" file with content:
"""
loader_collapsed_paths:
- plugins/nested
"""
When I run bridgetown build
Then I should get a zero exit status
And the output directory should exist
And I should see "Zeitwerk specific dir" in "output/foo/index.html"

Scenario: Allow collapsed Zeitwerk dirs using globs
Given I have a "plugins/nested" directory
And I have a "plugins/nested/top_level.rb" file with content:
"""
module TopLevel
Bridgetown::Hooks.register :site, :after_reset do |site|
pg = Bridgetown::GeneratedPage.new(site, site.source, "/", "foo.html")
pg.content = "Zeitwerk glob dir"

site.generated_pages << pg
end
end
"""
And I have a "bridgetown.config.yml" file with content:
"""
loader_collapsed_paths:
- plugins/*
"""
When I run bridgetown build
Then I should get a zero exit status
And the output directory should exist
And I should see "Zeitwerk glob dir" in "output/foo/index.html"
1 change: 1 addition & 0 deletions bridgetown-core/features/support/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def self.root_files
".bridgetown-webpack/manifest.json",
"bridgetown.config.yml",
"plugins",
"plugins/nested",
"frontend",
]
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def configure_cache
Bridgetown::Cache.disable_disk_cache! if config["disable_disk_cache"]
end

def configure_component_paths
def configure_component_paths # rubocop:todo Metrics/AbcSize
# Loop through plugins paths first
plugin_components_load_paths = Bridgetown::PluginManager.source_manifests
.map(&:components).compact
Expand All @@ -172,7 +172,10 @@ def configure_component_paths
end
end

@components_load_paths = plugin_components_load_paths + local_components_load_paths
config.components_load_paths = plugin_components_load_paths + local_components_load_paths
# Because "first constant wins" in Zeitwerk, we need to load the local
# source components _before_ we load any from plugins
config.autoload_paths += config.components_load_paths.reverse
end

def configure_file_read_opts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
class Bridgetown::Site
module Extensible
# Load necessary libraries, plugins, converters, and generators.
# This is only ever run once for the lifecycle of the site object.
# @see Converter
# @see Generator
# @see PluginManager
# @return [void]
def setup
plugin_manager.require_plugin_files
plugin_manager.setup_component_loaders
loaders_manager.setup_loaders
self.converters = instantiate_subclasses(Bridgetown::Converter)
self.generators = instantiate_subclasses(Bridgetown::Generator)
end
Expand Down
Loading