From 884b333a381a78d32295e91e496d854dc9f7c74d Mon Sep 17 00:00:00 2001 From: Jared White Date: Sun, 1 Dec 2024 10:27:08 -0800 Subject: [PATCH] Switch to `.bridgetown-cache/live_reload.txt` as the file to watch for live reload Also some routes plugin-related fixes Fixes #940 --- bridgetown-core/lib/bridgetown-core.rb | 17 +++++++++----- .../concerns/site/fast_refreshable.rb | 22 +++++++++++++------ .../bridgetown-core/concerns/site/writable.rb | 6 +++++ .../lib/bridgetown-core/rack/routes.rb | 3 +-- .../lib/roda/plugins/bridgetown_routes.rb | 4 ++++ 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/bridgetown-core/lib/bridgetown-core.rb b/bridgetown-core/lib/bridgetown-core.rb index 3a9dba1de..ff4522b5b 100644 --- a/bridgetown-core/lib/bridgetown-core.rb +++ b/bridgetown-core/lib/bridgetown-core.rb @@ -365,11 +365,18 @@ def sanitized_path(base_directory, questionable_path) # # @return [String] the path to the cached errors file def build_errors_path - File.join( - (Bridgetown::Current.site&.config || Bridgetown::Current.preloaded_configuration).root_dir, - ".bridgetown-cache", - "build_errors.txt" - ) + site_config = Bridgetown::Current.site&.config || Bridgetown::Current.preloaded_configuration + File.join(site_config.root_dir, site_config.cache_dir, "build_errors.txt") + end + + # This file gets touched each time there's a new build, which then triggers live reload + # in the browser. + # + # @see Bridgetown::Rack::Routes.setup_live_reload + # @return [String] the path to the empty file being watched + def live_reload_path + site_config = Bridgetown::Current.site&.config || Bridgetown::Current.preloaded_configuration + File.join(site_config.root_dir, site_config.cache_dir, "live_reload.txt") end end diff --git a/bridgetown-core/lib/bridgetown-core/concerns/site/fast_refreshable.rb b/bridgetown-core/lib/bridgetown-core/concerns/site/fast_refreshable.rb index 2b896727a..60b08e8a1 100644 --- a/bridgetown-core/lib/bridgetown-core/concerns/site/fast_refreshable.rb +++ b/bridgetown-core/lib/bridgetown-core/concerns/site/fast_refreshable.rb @@ -10,6 +10,7 @@ def fast_refresh(paths = [], reload_if_needed: false) # rubocop:todo Metrics @fast_refresh_ordering = 0 full_abort = false found_gen_pages = false + found_route_file = false paths.each do |path| # rubocop:todo Metrics found_res = resources.select do |resource| resource.id.start_with?("repo://") && in_source_dir(resource.relative_path) == path @@ -28,7 +29,13 @@ def fast_refresh(paths = [], reload_if_needed: false) # rubocop:todo Metrics self, layout.instance_variable_get(:@base), layout.name ) end - next unless found_res.any? || pages.any? + + if config.key?(:routes) # carve out fast refresh track for the routes plugin + found_route_file = config.routes.source_paths.any? do |routes_dir| + path.start_with?(in_source_dir(routes_dir)) + end + end + next unless found_res.any? || pages.any? || found_route_file if pages.any? found_gen_pages = true @@ -48,7 +55,7 @@ def fast_refresh(paths = [], reload_if_needed: false) # rubocop:todo Metrics end marked_resources = resources.select(&:fast_refresh_order).sort_by(&:fast_refresh_order) - if full_abort || (marked_resources.empty? && !found_gen_pages) + if full_abort || (marked_resources.empty? && !found_gen_pages && !found_route_file) # Darn, a full reload is needed (unless we're on a super-fast track) if reload_if_needed Bridgetown::Hooks.trigger :site, :pre_reload, self, paths @@ -62,13 +69,14 @@ def fast_refresh(paths = [], reload_if_needed: false) # rubocop:todo Metrics Bridgetown::Hooks.trigger :site, :fast_refresh, self - liquid_renderer.reset - transform_resources_for_fast_refresh(marked_resources, found_gen_pages) - transform_generated_pages_for_fast_refresh - - FileUtils.touch(in_destination_dir("index.html")) + unless found_route_file + liquid_renderer.reset + transform_resources_for_fast_refresh(marked_resources, found_gen_pages) + transform_generated_pages_for_fast_refresh + end Bridgetown::Hooks.trigger :site, :post_write, self + touch_live_reload_file end private diff --git a/bridgetown-core/lib/bridgetown-core/concerns/site/writable.rb b/bridgetown-core/lib/bridgetown-core/concerns/site/writable.rb index 42eac53f1..fcd3fbb73 100644 --- a/bridgetown-core/lib/bridgetown-core/concerns/site/writable.rb +++ b/bridgetown-core/lib/bridgetown-core/concerns/site/writable.rb @@ -17,6 +17,7 @@ def write write_redirecting_index if config.prefix_default_locale Bridgetown::Hooks.trigger :site, :post_write, self + touch_live_reload_file end # Yields all content objects while looping through {#generated_pages}, @@ -69,4 +70,9 @@ def write_redirecting_index File.write(in_dest_dir("index.html"), index_html, mode: "wb") end end + + def touch_live_reload_file + FileUtils.mkdir_p File.dirname(Bridgetown.live_reload_path) + FileUtils.touch Bridgetown.live_reload_path + end end diff --git a/bridgetown-core/lib/bridgetown-core/rack/routes.rb b/bridgetown-core/lib/bridgetown-core/rack/routes.rb index 89640c044..3fbfef3f4 100644 --- a/bridgetown-core/lib/bridgetown-core/rack/routes.rb +++ b/bridgetown-core/lib/bridgetown-core/rack/routes.rb @@ -108,8 +108,7 @@ def load_all(roda_app) # @param app [Roda] def setup_live_reload(app) # rubocop:disable Metrics sleep_interval = 0.5 - file_to_check = File.join(Bridgetown::Current.preloaded_configuration.destination, - "index.html") + file_to_check = Bridgetown.live_reload_path errors_file = Bridgetown.build_errors_path app.request.get "_bridgetown/live_reload" do diff --git a/bridgetown-routes/lib/roda/plugins/bridgetown_routes.rb b/bridgetown-routes/lib/roda/plugins/bridgetown_routes.rb index 223a96adf..161440163 100644 --- a/bridgetown-routes/lib/roda/plugins/bridgetown_routes.rb +++ b/bridgetown-routes/lib/roda/plugins/bridgetown_routes.rb @@ -130,10 +130,14 @@ def view(view_class: Bridgetown::ERBView) module RequestMethods # This runs through all of the routes in the manifest, setting up Roda blocks for execution def file_routes + base_path = Bridgetown::Current.preloaded_configuration.base_path.delete_prefix("/") + scope.routes_manifest.routes.each do |route| file, localized_file_slugs, segment_keys = route localized_file_slugs.each do |slug| + on("") { scope.run_file_route(file, slug:) } if slug == "index" && !base_path.empty? + # This sets up an initial Roda route block at the slug, and handles segments as params # # _routes/nested/[slug].erb -> "nested/:slug"