From 00c4d92965eb24c3307ca9462a3c6e7376c0a312 Mon Sep 17 00:00:00 2001 From: Marcell Cruz <0000marcell@gmail.com> Date: Sat, 16 May 2026 15:36:54 -0300 Subject: [PATCH 01/10] Add configurable project_path option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add config.project_path setting with Rails.root.to_s fallback - Use configured path in debug visitor, meta tags, and template checking - Useful for Docker mounts and monorepo structures 💘 Generated with Crush Assisted-by: Crush:claude-sonnet-4.5 --- docs/docs/installation.md | 28 ++++++++++++++++++++++ lib/reactionview/config.rb | 2 ++ lib/reactionview/template/handlers/herb.rb | 12 ++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/docs/docs/installation.md b/docs/docs/installation.md index 50c58fd..181f16b 100644 --- a/docs/docs/installation.md +++ b/docs/docs/installation.md @@ -67,6 +67,34 @@ end This gives you all the benefits of Herb's validation, security features, and debugging tools for your existing templates. +### Advanced Configuration + +#### Custom Project Path + +If your project path differs from `Rails.root` (e.g., Docker mounts, monorepos), you can configure a custom path: + +:::code-group +```ruby [config/initializers/reactionview.rb] +ReActionView.configure do |config| + # Custom project path for editor integration and dev tools + config.project_path = "/custom/path/to/project" + + # Docker example: map container path to host path + # config.project_path = "/Users/you/myapp" + + # Monorepo example: parent directory + # config.project_path = File.expand_path("../../", Rails.root) +end +``` +::: + +This affects: +- Editor integration when clicking source locations in the browser +- The `herb-project-path` meta tag for dev tools +- Template path resolution in debug mode + +**Default**: `Rails.root.to_s` + ## Verify Installation Create a test template to verify ReActionView is working: diff --git a/lib/reactionview/config.rb b/lib/reactionview/config.rb index 0c8e9b5..0c6f095 100644 --- a/lib/reactionview/config.rb +++ b/lib/reactionview/config.rb @@ -5,12 +5,14 @@ class Config attr_accessor :intercept_erb attr_accessor :debug_mode attr_accessor :transform_visitors + attr_accessor :project_path attr_writer :validation_mode def initialize @intercept_erb = false @debug_mode = nil @transform_visitors = [] + @project_path = nil end def validation_mode diff --git a/lib/reactionview/template/handlers/herb.rb b/lib/reactionview/template/handlers/herb.rb index b34f4c2..47cef87 100644 --- a/lib/reactionview/template/handlers/herb.rb +++ b/lib/reactionview/template/handlers/herb.rb @@ -14,13 +14,13 @@ def call(template, source) if ::ReActionView.config.debug_mode_enabled? && local_template?(template) visitors << ::Herb::Engine::DebugVisitor.new( file_path: template.identifier, - project_path: Rails.root.to_s + project_path: project_path ) end config = { filename: template.identifier, - project_path: Rails.root.to_s, + project_path: project_path, validation_mode: ReActionView.config.validation_mode, content_for_head: reactionview_dev_tools_markup(template), visitors: visitors + ReActionView.config.transform_visitors, @@ -40,7 +40,7 @@ def layout_template?(template) def local_template?(template) return true unless template.respond_to?(:identifier) && template.identifier - template.identifier.start_with?(Rails.root.to_s) + template.identifier.start_with?(project_path) end def active_support_editor @@ -58,6 +58,10 @@ def editor_meta_tag %() end + def project_path + ::ReActionView.config.project_path || Rails.root.to_s + end + def reactionview_dev_tools_markup(template) return nil unless layout_template?(template) return nil unless local_template?(template) @@ -67,7 +71,7 @@ def reactionview_dev_tools_markup(template) if ::ReActionView.config.debug_mode_enabled? markup << <<~HTML - + #{editor_meta_tag} #{ActionController::Base.new.view_context.javascript_include_tag "reactionview-dev-tools.umd.js", defer: true} From 01f305a9fa6fc5277d9cbc76c41a071c206d8723 Mon Sep 17 00:00:00 2001 From: Marcell Cruz <0000marcell@gmail.com> Date: Sat, 23 May 2026 15:29:12 -0300 Subject: [PATCH 02/10] Fix project_fullpath --- README.md | 3 +++ docs/docs/installation.md | 17 +++++++------- .../reactionview/install_generator.rb | 3 +++ lib/reactionview/config.rb | 10 +++++++-- lib/reactionview/template/handlers/herb.rb | 22 ++++++++++++++----- 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 778f191..703e1d3 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,9 @@ ReActionView.configure do |config| # Enable debug mode config.debug_mode = Rails.env.development? + # Custom path for editor "open in editor" links (optional, defaults to Rails.root) + # config.project_fullpath = ENV.fetch('PROJECT_FULLPATH', Rails.root.to_s) + # Validation mode (:raise, :overlay, or :none) — defaults to :raise in test, :overlay otherwise # config.validation_mode = :overlay end diff --git a/docs/docs/installation.md b/docs/docs/installation.md index 181f16b..caf5d27 100644 --- a/docs/docs/installation.md +++ b/docs/docs/installation.md @@ -69,32 +69,33 @@ This gives you all the benefits of Herb's validation, security features, and deb ### Advanced Configuration -#### Custom Project Path +#### Custom Project Path for Editor Links -If your project path differs from `Rails.root` (e.g., Docker mounts, monorepos), you can configure a custom path: +If your project path differs from `Rails.root` (e.g., Docker mounts, monorepos), you can configure a custom path for editor "open in editor" links: :::code-group ```ruby [config/initializers/reactionview.rb] ReActionView.configure do |config| - # Custom project path for editor integration and dev tools - config.project_path = "/custom/path/to/project" + # Custom project path for editor integration (optional) + config.project_fullpath = "/custom/path/to/project" # Docker example: map container path to host path - # config.project_path = "/Users/you/myapp" + # config.project_fullpath = "/Users/you/myapp" # Monorepo example: parent directory - # config.project_path = File.expand_path("../../", Rails.root) + # config.project_fullpath = File.expand_path("../../", Rails.root) end ``` ::: This affects: - Editor integration when clicking source locations in the browser -- The `herb-project-path` meta tag for dev tools -- Template path resolution in debug mode +- The `herb-rails-root` meta tag for dev tools **Default**: `Rails.root.to_s` +**Note**: `project_path` (used for local template detection) is automatically set to `Rails.root` and cannot be configured. + ## Verify Installation Create a test template to verify ReActionView is working: diff --git a/lib/generators/reactionview/install_generator.rb b/lib/generators/reactionview/install_generator.rb index ccc5b1b..ac4f5bd 100644 --- a/lib/generators/reactionview/install_generator.rb +++ b/lib/generators/reactionview/install_generator.rb @@ -23,6 +23,9 @@ def create_initializer # Enable debug mode in development (adds debug attributes to HTML) config.debug_mode = Rails.env.development? + # Path used for editor "open in editor" links (optional, defaults to Rails.root) + # config.project_fullpath = ENV.fetch('PROJECT_FULLPATH', Rails.root.to_s) + # Validation mode (:raise, :overlay, or :none) — defaults to :raise in test, :overlay otherwise # config.validation_mode = :overlay diff --git a/lib/reactionview/config.rb b/lib/reactionview/config.rb index 0c6f095..905be26 100644 --- a/lib/reactionview/config.rb +++ b/lib/reactionview/config.rb @@ -5,14 +5,20 @@ class Config attr_accessor :intercept_erb attr_accessor :debug_mode attr_accessor :transform_visitors - attr_accessor :project_path + attr_accessor :project_fullpath attr_writer :validation_mode def initialize @intercept_erb = false @debug_mode = nil @transform_visitors = [] - @project_path = nil + @project_fullpath = nil + end + + def project_path + return nil unless defined?(Rails) + + Rails.root.to_s end def validation_mode diff --git a/lib/reactionview/template/handlers/herb.rb b/lib/reactionview/template/handlers/herb.rb index 47cef87..6b976bc 100644 --- a/lib/reactionview/template/handlers/herb.rb +++ b/lib/reactionview/template/handlers/herb.rb @@ -13,14 +13,14 @@ def call(template, source) if ::ReActionView.config.debug_mode_enabled? && local_template?(template) visitors << ::Herb::Engine::DebugVisitor.new( - file_path: template.identifier, - project_path: project_path + file_path: translate_path_for_editor(template.identifier), + project_path: project_fullpath ) end config = { filename: template.identifier, - project_path: project_path, + project_path: project_fullpath, validation_mode: ReActionView.config.validation_mode, content_for_head: reactionview_dev_tools_markup(template), visitors: visitors + ReActionView.config.transform_visitors, @@ -59,7 +59,19 @@ def editor_meta_tag end def project_path - ::ReActionView.config.project_path || Rails.root.to_s + ::ReActionView.config.project_path + end + + def project_fullpath + ::ReActionView.config.project_fullpath || project_path + end + + def translate_path_for_editor(template_path) + return template_path unless project_fullpath && project_path + return template_path if project_fullpath == project_path + + # Replace Rails.root (container path) with project_fullpath (host path) + template_path.to_s.sub(project_path, project_fullpath) end def reactionview_dev_tools_markup(template) @@ -71,7 +83,7 @@ def reactionview_dev_tools_markup(template) if ::ReActionView.config.debug_mode_enabled? markup << <<~HTML - + #{editor_meta_tag} #{ActionController::Base.new.view_context.javascript_include_tag "reactionview-dev-tools.umd.js", defer: true} From 54478b0176fc389e39433bf488cff50b00616c6d Mon Sep 17 00:00:00 2001 From: Marcell Cruz <0000marcell@gmail.com> Date: Sat, 23 May 2026 15:30:16 -0300 Subject: [PATCH 03/10] update tests --- test/reactionview_test.rb | 2 +- test/snapshot_utils.rb | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/test/reactionview_test.rb b/test/reactionview_test.rb index 384b49e..0f27abf 100644 --- a/test/reactionview_test.rb +++ b/test/reactionview_test.rb @@ -4,6 +4,6 @@ class TestReActionView < Minitest::Spec test "has version number" do - refute_nil ::ReActionView::VERSION + assert_not_nil ::ReActionView::VERSION end end diff --git a/test/snapshot_utils.rb b/test/snapshot_utils.rb index 578d430..0d0c904 100644 --- a/test/snapshot_utils.rb +++ b/test/snapshot_utils.rb @@ -107,17 +107,17 @@ def snapshot_changed?(content, source, options = {}) previous_content = snapshot_file(source, options).read if previous_content == content - puts "\n\nSnapshot for '#{self.class.name} #{name}' didn't change: \n#{snapshot_file(source, options)}\n" + Rails.logger.debug { "\n\nSnapshot for '#{self.class.name} #{name}' didn't change: \n#{snapshot_file(source, options)}\n" } false else - puts "\n\nSnapshot for '#{self.class.name} #{name}' changed:\n" + Rails.logger.debug { "\n\nSnapshot for '#{self.class.name} #{name}' changed:\n" } - puts Difftastic::Differ.new(color: :always).diff_strings(previous_content, content) - puts "===============" + Rails.logger.debug Difftastic::Differ.new(color: :always).diff_strings(previous_content, content) + Rails.logger.debug "===============" true end else - puts "\n\nSnapshot for '#{self.class.name} #{name}' doesn't exist at: \n#{snapshot_file(source, options)}\n" + Rails.logger.debug { "\n\nSnapshot for '#{self.class.name} #{name}' doesn't exist at: \n#{snapshot_file(source, options)}\n" } true end end @@ -125,21 +125,21 @@ def snapshot_changed?(content, source, options = {}) def save_failures_to_snapshot(content, source, options = {}) return unless snapshot_changed?(content, source, options) - puts "\n==== [ Input for '#{self.class.name} #{name}' ] =====" - puts source - puts "\n\n" + Rails.logger.debug { "\n==== [ Input for '#{self.class.name} #{name}' ] =====" } + Rails.logger.debug source + Rails.logger.debug "\n\n" if !ENV["FORCE_UPDATE_SNAPSHOTS"].nil? || ask?("Do you want to update (or create) the snapshot for '#{self.class.name} #{name}'?") - puts "\nUpdating Snapshot for '#{self.class.name} #{name}' at: \n#{snapshot_file(source, options)}\n" + Rails.logger.debug { "\nUpdating Snapshot for '#{self.class.name} #{name}' at: \n#{snapshot_file(source, options)}\n" } FileUtils.mkdir_p(snapshot_file(source, options).dirname) snapshot_file(source, options).write(content) - puts "\nSnapshot for '#{self.class.name} #{name}' written: \n#{snapshot_file(source, options)}\n" + Rails.logger.debug { "\nSnapshot for '#{self.class.name} #{name}' written: \n#{snapshot_file(source, options)}\n" } else - puts "\nNot updating snapshot for '#{self.class.name} #{name}' at: \n#{snapshot_file(source, options)}.\n" + Rails.logger.debug { "\nNot updating snapshot for '#{self.class.name} #{name}' at: \n#{snapshot_file(source, options)}.\n" } end end @@ -157,7 +157,7 @@ def assert_snapshot_matches(actual, source, options = {}, mode: nil) raise unless snapshot_file(source, snapshot_opts).exist? if snapshot_file(source, snapshot_opts)&.read != actual - puts + Rails.logger.debug divider = "=" * `tput cols`.strip.to_i @@ -191,7 +191,7 @@ def snapshot_file(source, options = {}) # rubocop:disable Metrics/MethodLength opts_for_hash = options.except(:mode) - if opts_for_hash && !opts_for_hash.empty? + if opts_for_hash.present? options_hash = Digest::MD5.hexdigest(opts_for_hash.inspect) expected_snapshot_filename = "#{test_name}#{mode_suffix}_#{content_hash}-#{options_hash}.txt" else @@ -203,7 +203,7 @@ def snapshot_file(source, options = {}) # rubocop:disable Metrics/MethodLength return expected_snapshot_path if expected_snapshot_path.exist? - matching_md5_files = if opts_for_hash && !opts_for_hash.empty? + matching_md5_files = if opts_for_hash.present? Dir[base_path / "*#{mode_suffix}_#{content_hash}-#{options_hash}.txt"] else Dir[base_path / "*#{mode_suffix}_#{content_hash}.txt"] From eff88392d64df4204e3387c28d1531be03aa5752 Mon Sep 17 00:00:00 2001 From: Marcell Cruz <0000marcell@gmail.com> Date: Sat, 23 May 2026 15:36:20 -0300 Subject: [PATCH 04/10] revert snapshot tests rails specific configurations --- test/snapshot_utils.rb | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/snapshot_utils.rb b/test/snapshot_utils.rb index 0d0c904..578d430 100644 --- a/test/snapshot_utils.rb +++ b/test/snapshot_utils.rb @@ -107,17 +107,17 @@ def snapshot_changed?(content, source, options = {}) previous_content = snapshot_file(source, options).read if previous_content == content - Rails.logger.debug { "\n\nSnapshot for '#{self.class.name} #{name}' didn't change: \n#{snapshot_file(source, options)}\n" } + puts "\n\nSnapshot for '#{self.class.name} #{name}' didn't change: \n#{snapshot_file(source, options)}\n" false else - Rails.logger.debug { "\n\nSnapshot for '#{self.class.name} #{name}' changed:\n" } + puts "\n\nSnapshot for '#{self.class.name} #{name}' changed:\n" - Rails.logger.debug Difftastic::Differ.new(color: :always).diff_strings(previous_content, content) - Rails.logger.debug "===============" + puts Difftastic::Differ.new(color: :always).diff_strings(previous_content, content) + puts "===============" true end else - Rails.logger.debug { "\n\nSnapshot for '#{self.class.name} #{name}' doesn't exist at: \n#{snapshot_file(source, options)}\n" } + puts "\n\nSnapshot for '#{self.class.name} #{name}' doesn't exist at: \n#{snapshot_file(source, options)}\n" true end end @@ -125,21 +125,21 @@ def snapshot_changed?(content, source, options = {}) def save_failures_to_snapshot(content, source, options = {}) return unless snapshot_changed?(content, source, options) - Rails.logger.debug { "\n==== [ Input for '#{self.class.name} #{name}' ] =====" } - Rails.logger.debug source - Rails.logger.debug "\n\n" + puts "\n==== [ Input for '#{self.class.name} #{name}' ] =====" + puts source + puts "\n\n" if !ENV["FORCE_UPDATE_SNAPSHOTS"].nil? || ask?("Do you want to update (or create) the snapshot for '#{self.class.name} #{name}'?") - Rails.logger.debug { "\nUpdating Snapshot for '#{self.class.name} #{name}' at: \n#{snapshot_file(source, options)}\n" } + puts "\nUpdating Snapshot for '#{self.class.name} #{name}' at: \n#{snapshot_file(source, options)}\n" FileUtils.mkdir_p(snapshot_file(source, options).dirname) snapshot_file(source, options).write(content) - Rails.logger.debug { "\nSnapshot for '#{self.class.name} #{name}' written: \n#{snapshot_file(source, options)}\n" } + puts "\nSnapshot for '#{self.class.name} #{name}' written: \n#{snapshot_file(source, options)}\n" else - Rails.logger.debug { "\nNot updating snapshot for '#{self.class.name} #{name}' at: \n#{snapshot_file(source, options)}.\n" } + puts "\nNot updating snapshot for '#{self.class.name} #{name}' at: \n#{snapshot_file(source, options)}.\n" end end @@ -157,7 +157,7 @@ def assert_snapshot_matches(actual, source, options = {}, mode: nil) raise unless snapshot_file(source, snapshot_opts).exist? if snapshot_file(source, snapshot_opts)&.read != actual - Rails.logger.debug + puts divider = "=" * `tput cols`.strip.to_i @@ -191,7 +191,7 @@ def snapshot_file(source, options = {}) # rubocop:disable Metrics/MethodLength opts_for_hash = options.except(:mode) - if opts_for_hash.present? + if opts_for_hash && !opts_for_hash.empty? options_hash = Digest::MD5.hexdigest(opts_for_hash.inspect) expected_snapshot_filename = "#{test_name}#{mode_suffix}_#{content_hash}-#{options_hash}.txt" else @@ -203,7 +203,7 @@ def snapshot_file(source, options = {}) # rubocop:disable Metrics/MethodLength return expected_snapshot_path if expected_snapshot_path.exist? - matching_md5_files = if opts_for_hash.present? + matching_md5_files = if opts_for_hash && !opts_for_hash.empty? Dir[base_path / "*#{mode_suffix}_#{content_hash}-#{options_hash}.txt"] else Dir[base_path / "*#{mode_suffix}_#{content_hash}.txt"] From ac14984d6972876b366354b6c428e64041729ec3 Mon Sep 17 00:00:00 2001 From: Marcell Cruz <0000marcell@gmail.com> Date: Mon, 1 Jun 2026 18:00:59 -0300 Subject: [PATCH 05/10] revert test change --- test/reactionview_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/reactionview_test.rb b/test/reactionview_test.rb index 0f27abf..384b49e 100644 --- a/test/reactionview_test.rb +++ b/test/reactionview_test.rb @@ -4,6 +4,6 @@ class TestReActionView < Minitest::Spec test "has version number" do - assert_not_nil ::ReActionView::VERSION + refute_nil ::ReActionView::VERSION end end From f7cc93a70b04fbfa6822838bb40effe514ff5ea3 Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Sat, 8 Aug 2026 02:01:28 +0200 Subject: [PATCH 06/10] Rename back to `herb-project-path` --- docs/docs/installation.md | 2 +- javascript/packages/dev-tools/src/index.ts | 6 +----- lib/reactionview/template/handlers/herb.rb | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/docs/installation.md b/docs/docs/installation.md index caf5d27..925bfdd 100644 --- a/docs/docs/installation.md +++ b/docs/docs/installation.md @@ -90,7 +90,7 @@ end This affects: - Editor integration when clicking source locations in the browser -- The `herb-rails-root` meta tag for dev tools +- The `herb-project-path` meta tag for dev tools **Default**: `Rails.root.to_s` diff --git a/javascript/packages/dev-tools/src/index.ts b/javascript/packages/dev-tools/src/index.ts index 7adf7b7..f415d73 100644 --- a/javascript/packages/dev-tools/src/index.ts +++ b/javascript/packages/dev-tools/src/index.ts @@ -86,11 +86,7 @@ if (typeof window !== "undefined" && typeof document !== "undefined") { isInitializing = true try { - let projectPath: string | undefined - const railsRoot = document.querySelector(`meta[name="herb-rails-root"]`)?.getAttribute("content") - if (railsRoot) { - projectPath = railsRoot - } + const projectPath = document.querySelector(`meta[name="herb-project-path"]`)?.getAttribute("content") ?? undefined initReActionViewDevTools({ projectPath, diff --git a/lib/reactionview/template/handlers/herb.rb b/lib/reactionview/template/handlers/herb.rb index 6b976bc..645e492 100644 --- a/lib/reactionview/template/handlers/herb.rb +++ b/lib/reactionview/template/handlers/herb.rb @@ -83,7 +83,7 @@ def reactionview_dev_tools_markup(template) if ::ReActionView.config.debug_mode_enabled? markup << <<~HTML - + #{editor_meta_tag} #{ActionController::Base.new.view_context.javascript_include_tag "reactionview-dev-tools.umd.js", defer: true} From f92e3303f241e02a44e10fc669513e6cd64399df Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Sat, 8 Aug 2026 02:27:10 +0200 Subject: [PATCH 07/10] Rename `project_fullpath` to `project_path` --- Gemfile | 1 + Gemfile.lock | 2 + README.md | 2 +- docs/docs/installation.md | 12 +- gemfiles/rails_7_0.gemfile | 3 +- gemfiles/rails_7_0.gemfile.lock | 2 + gemfiles/rails_7_1.gemfile | 3 +- gemfiles/rails_7_1.gemfile.lock | 2 + gemfiles/rails_7_2.gemfile | 3 +- gemfiles/rails_7_2.gemfile.lock | 2 + gemfiles/rails_8_0.gemfile | 3 +- gemfiles/rails_8_0.gemfile.lock | 2 + gemfiles/rails_8_1.gemfile | 3 +- gemfiles/rails_8_1.gemfile.lock | 2 + gemfiles/rails_8_2.gemfile | 3 +- gemfiles/rails_8_2.gemfile.lock | 2 + .../reactionview/install_generator.rb | 2 +- lib/reactionview/config.rb | 8 +- lib/reactionview/template/handlers/herb.rb | 25 ++-- test/reactionview/config_test.rb | 27 ++++ test/snapshot_utils.rb | 8 +- ...piled_23f372c5835bd8e5809427a8bfe433ca.txt | 2 + ...piled_15299f7b9059f08ba4360b398f86c031.txt | 2 + ...uated_4d3a28975f5f90eefab8a7f79760fa4e.txt | 1 + test/template/handlers/project_path_test.rb | 118 ++++++++++++++++++ test/test_helper.rb | 1 + 26 files changed, 202 insertions(+), 39 deletions(-) create mode 100644 test/snapshots/re_action_view/project_path_test/test_0006_compiled_output_without_a_configured_project_path_compiled_23f372c5835bd8e5809427a8bfe433ca.txt create mode 100644 test/snapshots/re_action_view/project_path_test/test_0007_compiled_output_with_a_configured_project_path_compiled_15299f7b9059f08ba4360b398f86c031.txt create mode 100644 test/snapshots/re_action_view/project_path_test/test_0008_evaluated_output_with_a_configured_project_path_evaluated_4d3a28975f5f90eefab8a7f79760fa4e.txt create mode 100644 test/template/handlers/project_path_test.rb diff --git a/Gemfile b/Gemfile index c0bea54..c9fa00f 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,7 @@ gem "appraisal" gem "actionview", "~> 8.1" gem "maxitest", "~> 7.0" gem "minitest-difftastic" +gem "minitest-mock" gem "railties", "~> 8.1" gem "rake", "~> 13.0" gem "readline", "~> 0.0.4" diff --git a/Gemfile.lock b/Gemfile.lock index cc04bb4..18cac3d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -93,6 +93,7 @@ GEM prism (~> 1.5) minitest-difftastic (0.2.1) difftastic (~> 0.6) + minitest-mock (5.27.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) nokogiri (1.19.4-aarch64-linux-musl) @@ -203,6 +204,7 @@ DEPENDENCIES appraisal maxitest (~> 7.0) minitest-difftastic + minitest-mock railties (~> 8.1) rake (~> 13.0) reactionview! diff --git a/README.md b/README.md index 703e1d3..2c80b10 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ ReActionView.configure do |config| config.debug_mode = Rails.env.development? # Custom path for editor "open in editor" links (optional, defaults to Rails.root) - # config.project_fullpath = ENV.fetch('PROJECT_FULLPATH', Rails.root.to_s) + # config.project_path = ENV.fetch('PROJECT_PATH', Rails.root.to_s) # Validation mode (:raise, :overlay, or :none) — defaults to :raise in test, :overlay otherwise # config.validation_mode = :overlay diff --git a/docs/docs/installation.md b/docs/docs/installation.md index 925bfdd..e70b407 100644 --- a/docs/docs/installation.md +++ b/docs/docs/installation.md @@ -77,13 +77,13 @@ If your project path differs from `Rails.root` (e.g., Docker mounts, monorepos), ```ruby [config/initializers/reactionview.rb] ReActionView.configure do |config| # Custom project path for editor integration (optional) - config.project_fullpath = "/custom/path/to/project" - + config.project_path = "/custom/path/to/project" + # Docker example: map container path to host path - # config.project_fullpath = "/Users/you/myapp" - + # config.project_path = "/Users/you/myapp" + # Monorepo example: parent directory - # config.project_fullpath = File.expand_path("../../", Rails.root) + # config.project_path = File.expand_path("../../", Rails.root) end ``` ::: @@ -94,7 +94,7 @@ This affects: **Default**: `Rails.root.to_s` -**Note**: `project_path` (used for local template detection) is automatically set to `Rails.root` and cannot be configured. +**Note**: local template detection always uses `Rails.root` and is unaffected by this setting. ## Verify Installation diff --git a/gemfiles/rails_7_0.gemfile b/gemfiles/rails_7_0.gemfile index 16b7619..40e52e6 100644 --- a/gemfiles/rails_7_0.gemfile +++ b/gemfiles/rails_7_0.gemfile @@ -2,10 +2,11 @@ source "https://rubygems.org" -gem "actionview", "~> 7.0.0" gem "appraisal" +gem "actionview", "~> 7.0.0" gem "maxitest", "~> 7.0" gem "minitest-difftastic" +gem "minitest-mock" gem "railties", "~> 7.0.0" gem "rake", "~> 13.0" gem "readline", "~> 0.0.4" diff --git a/gemfiles/rails_7_0.gemfile.lock b/gemfiles/rails_7_0.gemfile.lock index 22eeca0..f2dcfdf 100644 --- a/gemfiles/rails_7_0.gemfile.lock +++ b/gemfiles/rails_7_0.gemfile.lock @@ -85,6 +85,7 @@ GEM prism (~> 1.5) minitest-difftastic (0.2.1) difftastic (~> 0.6) + minitest-mock (5.27.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -175,6 +176,7 @@ DEPENDENCIES appraisal maxitest (~> 7.0) minitest-difftastic + minitest-mock railties (~> 7.0.0) rake (~> 13.0) reactionview! diff --git a/gemfiles/rails_7_1.gemfile b/gemfiles/rails_7_1.gemfile index 98f051b..274dbc8 100644 --- a/gemfiles/rails_7_1.gemfile +++ b/gemfiles/rails_7_1.gemfile @@ -2,10 +2,11 @@ source "https://rubygems.org" -gem "actionview", "~> 7.1.0" gem "appraisal" +gem "actionview", "~> 7.1.0" gem "maxitest", "~> 7.0" gem "minitest-difftastic" +gem "minitest-mock" gem "railties", "~> 7.1.0" gem "rake", "~> 13.0" gem "readline", "~> 0.0.4" diff --git a/gemfiles/rails_7_1.gemfile.lock b/gemfiles/rails_7_1.gemfile.lock index 21da859..5992830 100644 --- a/gemfiles/rails_7_1.gemfile.lock +++ b/gemfiles/rails_7_1.gemfile.lock @@ -97,6 +97,7 @@ GEM prism (~> 1.5) minitest-difftastic (0.2.1) difftastic (~> 0.6) + minitest-mock (5.27.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -207,6 +208,7 @@ DEPENDENCIES appraisal maxitest (~> 7.0) minitest-difftastic + minitest-mock railties (~> 7.1.0) rake (~> 13.0) reactionview! diff --git a/gemfiles/rails_7_2.gemfile b/gemfiles/rails_7_2.gemfile index c54166e..b0f8a0f 100644 --- a/gemfiles/rails_7_2.gemfile +++ b/gemfiles/rails_7_2.gemfile @@ -2,10 +2,11 @@ source "https://rubygems.org" -gem "actionview", "~> 7.2.0" gem "appraisal" +gem "actionview", "~> 7.2.0" gem "maxitest", "~> 7.0" gem "minitest-difftastic" +gem "minitest-mock" gem "railties", "~> 7.2.0" gem "rake", "~> 13.0" gem "readline", "~> 0.0.4" diff --git a/gemfiles/rails_7_2.gemfile.lock b/gemfiles/rails_7_2.gemfile.lock index 4d94390..209cb29 100644 --- a/gemfiles/rails_7_2.gemfile.lock +++ b/gemfiles/rails_7_2.gemfile.lock @@ -97,6 +97,7 @@ GEM prism (~> 1.5) minitest-difftastic (0.2.1) difftastic (~> 0.6) + minitest-mock (5.27.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) nokogiri (1.19.4-aarch64-linux-musl) @@ -207,6 +208,7 @@ DEPENDENCIES appraisal maxitest (~> 7.0) minitest-difftastic + minitest-mock railties (~> 7.2.0) rake (~> 13.0) reactionview! diff --git a/gemfiles/rails_8_0.gemfile b/gemfiles/rails_8_0.gemfile index a2a9980..f2e4e76 100644 --- a/gemfiles/rails_8_0.gemfile +++ b/gemfiles/rails_8_0.gemfile @@ -2,10 +2,11 @@ source "https://rubygems.org" -gem "actionview", "~> 8.0.0" gem "appraisal" +gem "actionview", "~> 8.0.0" gem "maxitest", "~> 7.0" gem "minitest-difftastic" +gem "minitest-mock" gem "railties", "~> 8.0.0" gem "rake", "~> 13.0" gem "readline", "~> 0.0.4" diff --git a/gemfiles/rails_8_0.gemfile.lock b/gemfiles/rails_8_0.gemfile.lock index ad37d48..b3cb8e8 100644 --- a/gemfiles/rails_8_0.gemfile.lock +++ b/gemfiles/rails_8_0.gemfile.lock @@ -94,6 +94,7 @@ GEM prism (~> 1.5) minitest-difftastic (0.2.1) difftastic (~> 0.6) + minitest-mock (5.27.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) nokogiri (1.19.4-aarch64-linux-musl) @@ -204,6 +205,7 @@ DEPENDENCIES appraisal maxitest (~> 7.0) minitest-difftastic + minitest-mock railties (~> 8.0.0) rake (~> 13.0) reactionview! diff --git a/gemfiles/rails_8_1.gemfile b/gemfiles/rails_8_1.gemfile index 0207b8e..16a644e 100644 --- a/gemfiles/rails_8_1.gemfile +++ b/gemfiles/rails_8_1.gemfile @@ -2,10 +2,11 @@ source "https://rubygems.org" -gem "actionview", "~> 8.1.0" gem "appraisal" +gem "actionview", "~> 8.1.0" gem "maxitest", "~> 7.0" gem "minitest-difftastic" +gem "minitest-mock" gem "railties", "~> 8.1.0" gem "rake", "~> 13.0" gem "readline", "~> 0.0.4" diff --git a/gemfiles/rails_8_1.gemfile.lock b/gemfiles/rails_8_1.gemfile.lock index 81a473a..4043cdf 100644 --- a/gemfiles/rails_8_1.gemfile.lock +++ b/gemfiles/rails_8_1.gemfile.lock @@ -93,6 +93,7 @@ GEM prism (~> 1.5) minitest-difftastic (0.2.1) difftastic (~> 0.6) + minitest-mock (5.27.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) nokogiri (1.19.4-aarch64-linux-musl) @@ -203,6 +204,7 @@ DEPENDENCIES appraisal maxitest (~> 7.0) minitest-difftastic + minitest-mock railties (~> 8.1.0) rake (~> 13.0) reactionview! diff --git a/gemfiles/rails_8_2.gemfile b/gemfiles/rails_8_2.gemfile index 913bcaf..4b8caf2 100644 --- a/gemfiles/rails_8_2.gemfile +++ b/gemfiles/rails_8_2.gemfile @@ -2,10 +2,11 @@ source "https://rubygems.org" -gem "actionview", github: "rails/rails" gem "appraisal" +gem "actionview", github: "rails/rails" gem "maxitest", "~> 7.0" gem "minitest-difftastic" +gem "minitest-mock" gem "railties", github: "rails/rails" gem "rake", "~> 13.0" gem "readline", "~> 0.0.4" diff --git a/gemfiles/rails_8_2.gemfile.lock b/gemfiles/rails_8_2.gemfile.lock index 7d28a5b..b230149 100644 --- a/gemfiles/rails_8_2.gemfile.lock +++ b/gemfiles/rails_8_2.gemfile.lock @@ -110,6 +110,7 @@ GEM prism (~> 1.5) minitest-difftastic (0.2.1) difftastic (~> 0.6) + minitest-mock (5.27.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) nokogiri (1.19.4-aarch64-linux-musl) @@ -216,6 +217,7 @@ DEPENDENCIES appraisal maxitest (~> 7.0) minitest-difftastic + minitest-mock railties! rake (~> 13.0) reactionview! diff --git a/lib/generators/reactionview/install_generator.rb b/lib/generators/reactionview/install_generator.rb index ac4f5bd..4ca6060 100644 --- a/lib/generators/reactionview/install_generator.rb +++ b/lib/generators/reactionview/install_generator.rb @@ -24,7 +24,7 @@ def create_initializer config.debug_mode = Rails.env.development? # Path used for editor "open in editor" links (optional, defaults to Rails.root) - # config.project_fullpath = ENV.fetch('PROJECT_FULLPATH', Rails.root.to_s) + # config.project_path = ENV.fetch('PROJECT_PATH', Rails.root.to_s) # Validation mode (:raise, :overlay, or :none) — defaults to :raise in test, :overlay otherwise # config.validation_mode = :overlay diff --git a/lib/reactionview/config.rb b/lib/reactionview/config.rb index 905be26..d903af4 100644 --- a/lib/reactionview/config.rb +++ b/lib/reactionview/config.rb @@ -5,20 +5,18 @@ class Config attr_accessor :intercept_erb attr_accessor :debug_mode attr_accessor :transform_visitors - attr_accessor :project_fullpath + attr_writer :project_path attr_writer :validation_mode def initialize @intercept_erb = false @debug_mode = nil @transform_visitors = [] - @project_fullpath = nil + @project_path = nil end def project_path - return nil unless defined?(Rails) - - Rails.root.to_s + @project_path || Rails.root.to_s end def validation_mode diff --git a/lib/reactionview/template/handlers/herb.rb b/lib/reactionview/template/handlers/herb.rb index 645e492..bb6ac61 100644 --- a/lib/reactionview/template/handlers/herb.rb +++ b/lib/reactionview/template/handlers/herb.rb @@ -14,13 +14,13 @@ def call(template, source) if ::ReActionView.config.debug_mode_enabled? && local_template?(template) visitors << ::Herb::Engine::DebugVisitor.new( file_path: translate_path_for_editor(template.identifier), - project_path: project_fullpath + project_path: ::ReActionView.config.project_path ) end config = { filename: template.identifier, - project_path: project_fullpath, + project_path: Rails.root.to_s, validation_mode: ReActionView.config.validation_mode, content_for_head: reactionview_dev_tools_markup(template), visitors: visitors + ReActionView.config.transform_visitors, @@ -40,7 +40,7 @@ def layout_template?(template) def local_template?(template) return true unless template.respond_to?(:identifier) && template.identifier - template.identifier.start_with?(project_path) + template.identifier.start_with?(Rails.root.to_s) end def active_support_editor @@ -58,20 +58,13 @@ def editor_meta_tag %() end - def project_path - ::ReActionView.config.project_path - end - - def project_fullpath - ::ReActionView.config.project_fullpath || project_path - end - def translate_path_for_editor(template_path) - return template_path unless project_fullpath && project_path - return template_path if project_fullpath == project_path + rails_root = Rails.root.to_s + project_path = ::ReActionView.config.project_path + + return template_path if project_path == rails_root - # Replace Rails.root (container path) with project_fullpath (host path) - template_path.to_s.sub(project_path, project_fullpath) + template_path.to_s.sub(rails_root, project_path) end def reactionview_dev_tools_markup(template) @@ -83,7 +76,7 @@ def reactionview_dev_tools_markup(template) if ::ReActionView.config.debug_mode_enabled? markup << <<~HTML - + #{editor_meta_tag} #{ActionController::Base.new.view_context.javascript_include_tag "reactionview-dev-tools.umd.js", defer: true} diff --git a/test/reactionview/config_test.rb b/test/reactionview/config_test.rb index 613e003..7164c53 100644 --- a/test/reactionview/config_test.rb +++ b/test/reactionview/config_test.rb @@ -58,4 +58,31 @@ def config.test? assert_equal :raise, config.validation_mode end + + test "project_path defaults to Rails.root" do + config = ReActionView::Config.new + + Rails.stub(:root, Pathname.new("/app")) do + assert_equal "/app", config.project_path + end + end + + test "project_path returns the configured value" do + config = ReActionView::Config.new + config.project_path = "/Users/you/myapp" + + Rails.stub(:root, Pathname.new("/app")) do + assert_equal "/Users/you/myapp", config.project_path + end + end + + test "project_path falls back to Rails.root when reset to nil" do + config = ReActionView::Config.new + config.project_path = "/Users/you/myapp" + config.project_path = nil + + Rails.stub(:root, Pathname.new("/app")) do + assert_equal "/app", config.project_path + end + end end diff --git a/test/snapshot_utils.rb b/test/snapshot_utils.rb index 578d430..8ccc6fd 100644 --- a/test/snapshot_utils.rb +++ b/test/snapshot_utils.rb @@ -15,10 +15,10 @@ def ask?(prompt = "") end module SnapshotUtils # rubocop:disable Metrics/ModuleLength - def assert_compiled_snapshot(source, handler: ReActionView::Template::Handlers::ERB, virtual_path: "test", format: :html, locals: [], options: {}) # rubocop:disable Metrics/ParameterLists + def assert_compiled_snapshot(source, handler: ReActionView::Template::Handlers::ERB, virtual_path: "test", identifier: "test_template", format: :html, locals: [], options: {}) # rubocop:disable Metrics/ParameterLists,Layout/LineLength template = ActionView::Template.new( source, - "test_template", + identifier, handler, virtual_path: virtual_path, format: format, @@ -53,10 +53,10 @@ def assert_compiled_snapshot(source, handler: ReActionView::Template::Handlers:: compiled_source end - def assert_evaluated_snapshot(source, ivars: {}, options: {}, handler: ReActionView::Template::Handlers::ERB, virtual_path: "test", format: :html, locals: []) # rubocop:disable Metrics/ParameterLists,Layout/LineLength,Metrics/MethodLength + def assert_evaluated_snapshot(source, ivars: {}, options: {}, handler: ReActionView::Template::Handlers::ERB, virtual_path: "test", identifier: "test_template", format: :html, locals: []) # rubocop:disable Metrics/ParameterLists,Layout/LineLength,Metrics/MethodLength template = ActionView::Template.new( source, - "test_template", + identifier, handler, virtual_path: virtual_path, format: format, diff --git a/test/snapshots/re_action_view/project_path_test/test_0006_compiled_output_without_a_configured_project_path_compiled_23f372c5835bd8e5809427a8bfe433ca.txt b/test/snapshots/re_action_view/project_path_test/test_0006_compiled_output_without_a_configured_project_path_compiled_23f372c5835bd8e5809427a8bfe433ca.txt new file mode 100644 index 0000000..777a6b6 --- /dev/null +++ b/test/snapshots/re_action_view/project_path_test/test_0006_compiled_output_without_a_configured_project_path_compiled_23f372c5835bd8e5809427a8bfe433ca.txt @@ -0,0 +1,2 @@ + @output_buffer.safe_append='

Hello

'.freeze; +@output_buffer \ No newline at end of file diff --git a/test/snapshots/re_action_view/project_path_test/test_0007_compiled_output_with_a_configured_project_path_compiled_15299f7b9059f08ba4360b398f86c031.txt b/test/snapshots/re_action_view/project_path_test/test_0007_compiled_output_with_a_configured_project_path_compiled_15299f7b9059f08ba4360b398f86c031.txt new file mode 100644 index 0000000..8f926eb --- /dev/null +++ b/test/snapshots/re_action_view/project_path_test/test_0007_compiled_output_with_a_configured_project_path_compiled_15299f7b9059f08ba4360b398f86c031.txt @@ -0,0 +1,2 @@ + @output_buffer.safe_append='

Hello

'.freeze; +@output_buffer \ No newline at end of file diff --git a/test/snapshots/re_action_view/project_path_test/test_0008_evaluated_output_with_a_configured_project_path_evaluated_4d3a28975f5f90eefab8a7f79760fa4e.txt b/test/snapshots/re_action_view/project_path_test/test_0008_evaluated_output_with_a_configured_project_path_evaluated_4d3a28975f5f90eefab8a7f79760fa4e.txt new file mode 100644 index 0000000..19e465b --- /dev/null +++ b/test/snapshots/re_action_view/project_path_test/test_0008_evaluated_output_with_a_configured_project_path_evaluated_4d3a28975f5f90eefab8a7f79760fa4e.txt @@ -0,0 +1 @@ +

Hello

\ No newline at end of file diff --git a/test/template/handlers/project_path_test.rb b/test/template/handlers/project_path_test.rb new file mode 100644 index 0000000..241ca65 --- /dev/null +++ b/test/template/handlers/project_path_test.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +require_relative "../../test_helper" + +require "action_controller" + +class ReActionView::ProjectPathTest < Minitest::Spec + RAILS_ROOT = "/app" + HOST_PATH = "/Users/you/myapp" + VIEW = "/app/app/views/users/show.html.erb" + LAYOUT = "/app/app/views/layouts/application.html.erb" + + before do + @previous_debug_mode = ReActionView.config.debug_mode + + ReActionView.config.debug_mode = true + ReActionView.config.project_path = nil + end + + after do + ReActionView.config.debug_mode = @previous_debug_mode + ReActionView.config.project_path = nil + end + + def compile(source, identifier: VIEW, virtual_path: "users/show") + template = ActionView::Template.new( + source, + identifier, + ReActionView::Template::Handlers::Herb, + virtual_path: virtual_path, + format: :html, + locals: [] + ) + + Rails.stub(:root, Pathname.new(RAILS_ROOT)) do + ReActionView::Template::Handlers::Herb.call(template, source) + end + end + + test "editor path is left alone when project_path is not configured" do + compiled = compile("
Hello
") + + assert_includes compiled, %(data-herb-debug-file-full-path="/app/app/views/users/show.html.erb") + end + + test "editor path is rewritten to the configured project_path" do + ReActionView.config.project_path = HOST_PATH + + compiled = compile("
Hello
") + + assert_includes compiled, %(data-herb-debug-file-full-path="/Users/you/myapp/app/views/users/show.html.erb") + end + + test "relative path stays correct when the editor path is rewritten" do + ReActionView.config.project_path = HOST_PATH + + compiled = compile("
Hello
") + + assert_includes compiled, %(data-herb-debug-file-relative-path="app/views/users/show.html.erb") + end + + test "herb-project-path meta tag keeps Rails.root so it matches the herb dev server" do + ReActionView.config.project_path = HOST_PATH + + compiled = compile("", identifier: LAYOUT, virtual_path: "layouts/application") + + assert_includes compiled, %() + refute_includes compiled, %() + end + + test "templates outside Rails.root stay undecorated even when project_path matches them" do + ReActionView.config.project_path = HOST_PATH + + compiled = compile("
Hello
", identifier: "#{HOST_PATH}/app/views/users/show.html.erb") + + refute_includes compiled, "data-herb-debug" + end + + test "compiled output without a configured project_path" do + Rails.stub(:root, Pathname.new(RAILS_ROOT)) do + assert_compiled_snapshot( + "

Hello

", + handler: ReActionView::Template::Handlers::Herb, + identifier: VIEW, + virtual_path: "users/show", + options: { project_path: nil } + ) + end + end + + test "compiled output with a configured project_path" do + ReActionView.config.project_path = HOST_PATH + + Rails.stub(:root, Pathname.new(RAILS_ROOT)) do + assert_compiled_snapshot( + "

Hello

", + handler: ReActionView::Template::Handlers::Herb, + identifier: VIEW, + virtual_path: "users/show", + options: { project_path: HOST_PATH } + ) + end + end + + test "evaluated output with a configured project_path" do + ReActionView.config.project_path = HOST_PATH + + Rails.stub(:root, Pathname.new(RAILS_ROOT)) do + assert_evaluated_snapshot( + "

Hello

", + handler: ReActionView::Template::Handlers::Herb, + identifier: VIEW, + virtual_path: "users/show", + options: { project_path: HOST_PATH } + ) + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index c8dfc5f..2199d3e 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -10,6 +10,7 @@ require "maxitest/autorun" require "minitest/spec" +require "minitest/mock" require_relative "snapshot_utils" From 86b8323d4ff05a19b685e18eb4dca11102f54fff Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Sat, 8 Aug 2026 02:31:34 +0200 Subject: [PATCH 08/10] Cleanup --- gemfiles/rails_7_1.gemfile | 2 +- gemfiles/rails_7_2.gemfile | 2 +- gemfiles/rails_8_0.gemfile | 2 +- gemfiles/rails_8_1.gemfile | 2 +- gemfiles/rails_8_2.gemfile | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gemfiles/rails_7_1.gemfile b/gemfiles/rails_7_1.gemfile index 274dbc8..6d0b61f 100644 --- a/gemfiles/rails_7_1.gemfile +++ b/gemfiles/rails_7_1.gemfile @@ -2,8 +2,8 @@ source "https://rubygems.org" -gem "appraisal" gem "actionview", "~> 7.1.0" +gem "appraisal" gem "maxitest", "~> 7.0" gem "minitest-difftastic" gem "minitest-mock" diff --git a/gemfiles/rails_7_2.gemfile b/gemfiles/rails_7_2.gemfile index b0f8a0f..a9b174f 100644 --- a/gemfiles/rails_7_2.gemfile +++ b/gemfiles/rails_7_2.gemfile @@ -2,8 +2,8 @@ source "https://rubygems.org" -gem "appraisal" gem "actionview", "~> 7.2.0" +gem "appraisal" gem "maxitest", "~> 7.0" gem "minitest-difftastic" gem "minitest-mock" diff --git a/gemfiles/rails_8_0.gemfile b/gemfiles/rails_8_0.gemfile index f2e4e76..21b154a 100644 --- a/gemfiles/rails_8_0.gemfile +++ b/gemfiles/rails_8_0.gemfile @@ -2,8 +2,8 @@ source "https://rubygems.org" -gem "appraisal" gem "actionview", "~> 8.0.0" +gem "appraisal" gem "maxitest", "~> 7.0" gem "minitest-difftastic" gem "minitest-mock" diff --git a/gemfiles/rails_8_1.gemfile b/gemfiles/rails_8_1.gemfile index 16a644e..977063f 100644 --- a/gemfiles/rails_8_1.gemfile +++ b/gemfiles/rails_8_1.gemfile @@ -2,8 +2,8 @@ source "https://rubygems.org" -gem "appraisal" gem "actionview", "~> 8.1.0" +gem "appraisal" gem "maxitest", "~> 7.0" gem "minitest-difftastic" gem "minitest-mock" diff --git a/gemfiles/rails_8_2.gemfile b/gemfiles/rails_8_2.gemfile index 4b8caf2..32130c6 100644 --- a/gemfiles/rails_8_2.gemfile +++ b/gemfiles/rails_8_2.gemfile @@ -2,8 +2,8 @@ source "https://rubygems.org" -gem "appraisal" gem "actionview", github: "rails/rails" +gem "appraisal" gem "maxitest", "~> 7.0" gem "minitest-difftastic" gem "minitest-mock" From a2ce0fc9776d84ef5877d37ed606c73dc2e6d63b Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Sat, 8 Aug 2026 02:32:11 +0200 Subject: [PATCH 09/10] Update docs --- docs/docs/installation.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/docs/docs/installation.md b/docs/docs/installation.md index e70b407..e16182a 100644 --- a/docs/docs/installation.md +++ b/docs/docs/installation.md @@ -69,32 +69,29 @@ This gives you all the benefits of Herb's validation, security features, and deb ### Advanced Configuration -#### Custom Project Path for Editor Links +#### Custom Project Path for Editor Links -If your project path differs from `Rails.root` (e.g., Docker mounts, monorepos), you can configure a custom path for editor "open in editor" links: +When your app runs somewhere other than where its files live, such as a Docker bind mount, a devcontainer, or a VM, the paths Rails sees aren't paths your editor can open. `config.project_path` says where `Rails.root` is mounted on the machine running your editor, and rewrites "open in editor" links to match: :::code-group ```ruby [config/initializers/reactionview.rb] ReActionView.configure do |config| - # Custom project path for editor integration (optional) - config.project_path = "/custom/path/to/project" + # Where Rails.root is mounted on the machine running your editor + config.project_path = "/Users/you/myapp" - # Docker example: map container path to host path - # config.project_path = "/Users/you/myapp" - - # Monorepo example: parent directory - # config.project_path = File.expand_path("../../", Rails.root) + # Or take it from the environment + # config.project_path = ENV.fetch("PROJECT_PATH", Rails.root.to_s) end ``` ::: -This affects: -- Editor integration when clicking source locations in the browser -- The `herb-project-path` meta tag for dev tools +With `Rails.root` at `/app` inside the container, a template at `/app/app/views/users/show.html.erb` then opens as `/Users/you/myapp/app/views/users/show.html.erb`. **Default**: `Rails.root.to_s` -**Note**: local template detection always uses `Rails.root` and is unaffected by this setting. +::: info Only editor links are affected +Local template detection and the `herb-project-path` meta tag stay on `Rails.root`. The meta tag is compared against the path the `herb dev` server reports, so overriding it would make the dev tools treat the page as a different project and ignore it. +::: ## Verify Installation From 8bb7f035f37e7e0d52ecf77eca4deb37c0bc92c9 Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Sat, 8 Aug 2026 02:33:24 +0200 Subject: [PATCH 10/10] Cleanup --- gemfiles/rails_7_0.gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gemfiles/rails_7_0.gemfile b/gemfiles/rails_7_0.gemfile index 40e52e6..3d69615 100644 --- a/gemfiles/rails_7_0.gemfile +++ b/gemfiles/rails_7_0.gemfile @@ -2,8 +2,8 @@ source "https://rubygems.org" -gem "appraisal" gem "actionview", "~> 7.0.0" +gem "appraisal" gem "maxitest", "~> 7.0" gem "minitest-difftastic" gem "minitest-mock"