Module: StimulusPlumbers::Generators::CssEntrypoint

Included in:
InstallGenerator
Defined in:
lib/stimulus_plumbers/generators/css_entrypoint.rb

Constant Summary collapse

STIMULUS_PLUMBERS_CSS_ENTRY =
"STIMULUS_PLUMBERS_CSS_ENTRY"
ENTRY_CANDIDATES =

Shared with stimulus_plumbers_tailwind's InstallGenerator — checked in order, each path is another gem/tool's own default entry file. Detection is theme- agnostic: any of these may be the CSS entry regardless of which theme is active.

[
  "app/assets/stylesheets/application.tailwind.css", # tailwindcss-rails 2.x default
  "app/assets/tailwind/application.css",             # tailwindcss-rails 3.x+ default
  "app/assets/stylesheets/application.css",          # Rails/Propshaft default manifest
  "app/javascript/entrypoints/application.css"       # jsbundling-rails (esbuild/webpack) default
].freeze

Instance Method Summary collapse

Instance Method Details

#apply_edit(css_file, directive, stale_pattern:, anchor_pattern: nil) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/stimulus_plumbers/generators/css_entrypoint.rb', line 37

def apply_edit(css_file, directive, stale_pattern:, anchor_pattern: nil)
  content              = File.read(css_file)
  new_content, status  = content_edit(content, directive, stale_pattern: stale_pattern, anchor_pattern: anchor_pattern)

  if new_content
    File.write(css_file, new_content)
    say_status status, relative_to_destination(css_file), :green
  else
    say_status :identical, relative_to_destination(css_file)
  end
rescue Errno::EROFS, Errno::EACCES => e
  say "Could not update #{relative_to_destination(css_file)}: #{e.message}. Skipping.", :yellow
end

#content_edit(content, directive, stale_pattern:, anchor_pattern: nil) ⇒ Object

stale_pattern: is required — every call site needs stale-import detection, so making it optional would leave an untested "anchor without stale" state.



53
54
55
56
57
58
59
60
61
# File 'lib/stimulus_plumbers/generators/css_entrypoint.rb', line 53

def content_edit(content, directive, stale_pattern:, anchor_pattern: nil)
  return nil if content.include?(directive)

  if (existing = content.match(stale_pattern))
    return [content.sub(existing[0], directive), :update]
  end

  anchor_pattern ? insert_near_anchor(content, directive, anchor_pattern) : prepend(content, directive)
end

#entry_css_file(candidates:, env_var:) ⇒ Object



18
19
20
21
22
23
24
25
26
27
# File 'lib/stimulus_plumbers/generators/css_entrypoint.rb', line 18

def entry_css_file(candidates:, env_var:)
  if ENV[env_var]
    path = File.expand_path(ENV.fetch(env_var, nil))
    return path if File.exist?(path)
  end

  candidates
    .map { |c| File.join(destination_root, c) }
    .find { |f| File.exist?(f) }
end

#insert_near_anchor(content, directive, anchor_pattern) ⇒ Object



67
68
69
70
71
72
73
# File 'lib/stimulus_plumbers/generators/css_entrypoint.rb', line 67

def insert_near_anchor(content, directive, anchor_pattern)
  if (anchor = content.match(anchor_pattern))
    [content.sub(anchor[0], "#{anchor[0]}\n#{directive}"), :insert]
  else
    ["#{content.rstrip}\n#{directive}\n", :append]
  end
end

#prepend(content, directive) ⇒ Object



63
64
65
# File 'lib/stimulus_plumbers/generators/css_entrypoint.rb', line 63

def prepend(content, directive)
  ["#{directive}\n#{content}", :prepend]
end

#relative_to_destination(path) ⇒ Object



75
76
77
# File 'lib/stimulus_plumbers/generators/css_entrypoint.rb', line 75

def relative_to_destination(path)
  path.delete_prefix("#{destination_root}/")
end

#warn_entry_css_not_found(candidates:, env_var:, label:) ⇒ Object



29
30
31
32
33
34
35
# File 'lib/stimulus_plumbers/generators/css_entrypoint.rb', line 29

def warn_entry_css_not_found(candidates:, env_var:, label:)
  tried = candidates.map { |c| File.join(destination_root, c) }
  tried.unshift(File.expand_path(ENV[env_var])) if ENV[env_var]
  say "Could not find a #{label} entry file. Tried: #{tried.join(", ")}. " \
      "Set #{env_var}=/path/to/entry.css and re-run.",
      :red
end