Module: Seams::Generators::HostInjector
- Included in:
- AccountsGenerator, AdminGenerator, AuthGenerator, BillingGenerator, CoreGenerator, EngineGenerator, InstallGenerator, NotificationsGenerator, RemoveGenerator, TeamsGenerator
- Defined in:
- lib/seams/generators/host_injector.rb
Overview
Idempotent host-file edits used by every canonical generator. Mix into a Rails::Generators::Base subclass; the methods below delegate to Thor’s inject_into_file / append_to_file primitives but skip the edit if the host already contains the snippet.
Every method is safe to call when the target file is missing —it prints a yellow ‘skip` line so the user knows to do the edit themselves later.
Instance Method Summary collapse
- #host_inject_gem(name, *args, group: nil) ⇒ Object
- #host_inject_include_in_application_controller(concern_name) ⇒ Object
- #host_inject_include_in_user(concern_name) ⇒ Object
- #host_inject_mount(engine_class:, at:) ⇒ Object
-
#host_uninject_gem(name) ⇒ Object
Reverse of host_inject_gem — used by the remove generator.
- #host_uninject_include(file_relative, concern_name) ⇒ Object
- #host_uninject_mount(engine_class:) ⇒ Object
-
#routes_draw_anchor ⇒ Object
Matches the common ‘Rails.application.routes.draw do` forms: plain `do`, `do |routes|` block-arg, `do # comment`, and the rare `Rails::Application.routes.draw`.
Instance Method Details
#host_inject_gem(name, *args, group: nil) ⇒ Object
16 17 18 19 20 21 22 23 24 25 |
# File 'lib/seams/generators/host_injector.rb', line 16 def host_inject_gem(name, *args, group: nil) gemfile = host_path("Gemfile") return host_skip("Gemfile not found — add `gem #{name.inspect}` yourself") unless File.exist?(gemfile) return if File.read(gemfile).match?(/^\s*gem\s+["']#{Regexp.escape(name)}["']/) line = build_gem_line(name, args, group) say " inject Gemfile (gem \"#{name}\")", :green append_to_file(gemfile, "\n#{line}\n") end |
#host_inject_include_in_application_controller(concern_name) ⇒ Object
56 57 58 59 60 61 |
# File 'lib/seams/generators/host_injector.rb', line 56 def host_inject_include_in_application_controller(concern_name) host_inject_include( "app/controllers/application_controller.rb", "ApplicationController", concern_name, label: "ApplicationController" ) end |
#host_inject_include_in_user(concern_name) ⇒ Object
52 53 54 |
# File 'lib/seams/generators/host_injector.rb', line 52 def host_inject_include_in_user(concern_name) host_inject_include("app/models/user.rb", "User", concern_name, label: "User model") end |
#host_inject_mount(engine_class:, at:) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/seams/generators/host_injector.rb', line 27 def host_inject_mount(engine_class:, at:) routes = host_path("config/routes.rb") unless File.exist?(routes) return host_skip("config/routes.rb not found — add `mount #{engine_class}, at: \"#{at}\"` yourself") end # Word-boundary match on the engine class name so a sibling # `mount Auth::EngineExtras` doesn't trick us into thinking # `Auth::Engine` is already mounted. The boundary is "anything # that isn't a constant-name character" (`[\w:]` excluded). return if File.read(routes).match?(/\bmount\s+#{Regexp.escape(engine_class)}(?![\w:])/) say " inject config/routes.rb (mount #{engine_class})", :green inject_into_file(routes, after: routes_draw_anchor) do " mount #{engine_class}, at: \"#{at}\"\n" end end |
#host_uninject_gem(name) ⇒ Object
Reverse of host_inject_gem — used by the remove generator. Removes the ‘gem “<name>”` line if present.
65 66 67 68 69 70 71 72 |
# File 'lib/seams/generators/host_injector.rb', line 65 def host_uninject_gem(name) gemfile = host_path("Gemfile") return unless File.exist?(gemfile) new_content = File.read(gemfile).gsub(/^\s*gem\s+["']#{Regexp.escape(name)}["'][^\n]*\n/, "") File.write(gemfile, new_content) say " remove Gemfile (gem \"#{name}\")", :red end |
#host_uninject_include(file_relative, concern_name) ⇒ Object
87 88 89 90 91 92 93 94 |
# File 'lib/seams/generators/host_injector.rb', line 87 def host_uninject_include(file_relative, concern_name) full = host_path(file_relative) return unless File.exist?(full) new_content = File.read(full).gsub(/^\s*include\s+#{Regexp.escape(concern_name)}\s*\n/, "") File.write(full, new_content) say " remove #{file_relative} (include #{concern_name})", :red end |
#host_uninject_mount(engine_class:) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/seams/generators/host_injector.rb', line 74 def host_uninject_mount(engine_class:) routes = host_path("config/routes.rb") return unless File.exist?(routes) # Word-boundary match — see host_inject_mount. Without it, an # unrelated `mount Auth::EngineExtras` would match a remove of # `mount Auth::Engine` and silently delete the wrong line. pattern = /^\s*mount\s+#{Regexp.escape(engine_class)}(?![\w:])[^\n]*\n/ new_content = File.read(routes).gsub(pattern, "") File.write(routes, new_content) say " remove config/routes.rb (mount #{engine_class})", :red end |
#routes_draw_anchor ⇒ Object
Matches the common ‘Rails.application.routes.draw do` forms: plain `do`, `do |routes|` block-arg, `do # comment`, and the rare `Rails::Application.routes.draw`.
48 49 50 |
# File 'lib/seams/generators/host_injector.rb', line 48 def routes_draw_anchor /Rails(?:\.application|::Application)\.routes\.draw\s+do(?:\s*\|[^|]+\|)?[^\n]*\n/ end |