Module: GeneratorHelper

Instance Method Summary collapse

Instance Method Details

#add_documentation_reference(message, source) ⇒ Object



91
92
93
# File 'lib/generators/react_on_rails/generator_helper.rb', line 91

def add_documentation_reference(message, source)
  "#{message} \n#{source}"
end

#add_npm_dependencies(packages, dev: false) ⇒ Object

Safe wrapper for package_json operations



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/generators/react_on_rails/generator_helper.rb', line 23

def add_npm_dependencies(packages, dev: false)
  pj = package_json
  return false unless pj

  begin
    if dev
      pj.manager.add(packages, type: :dev, exact: true)
    else
      pj.manager.add(packages, exact: true)
    end
    true
  rescue StandardError => e
    puts "Warning: Could not add packages via package_json gem: #{e.message}"
    puts "Will fall back to direct npm commands."
    false
  end
end

#component_extension(options) ⇒ Object



95
96
97
# File 'lib/generators/react_on_rails/generator_helper.rb', line 95

def component_extension(options)
  options.typescript? ? "tsx" : "jsx"
end

#copy_file_and_missing_parent_directories(source_file, destination_file = nil) ⇒ Object



83
84
85
86
87
88
89
# File 'lib/generators/react_on_rails/generator_helper.rb', line 83

def copy_file_and_missing_parent_directories(source_file, destination_file = nil)
  destination_file ||= source_file
  destination_path = Pathname.new(destination_file)
  parent_directories = destination_path.dirname
  empty_directory(parent_directories) unless dest_dir_exists?(parent_directories)
  copy_file source_file, destination_file
end

#dest_dir_exists?(dir) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
50
# File 'lib/generators/react_on_rails/generator_helper.rb', line 47

def dest_dir_exists?(dir)
  dest_dir = File.join(destination_root, dir)
  Dir.exist?(dest_dir) ? dest_dir : nil
end

#dest_file_exists?(file) ⇒ Boolean

Takes a relative path from the destination root, such as ‘.gitignore` or `app/assets/javascripts/application.js`

Returns:

  • (Boolean)


42
43
44
45
# File 'lib/generators/react_on_rails/generator_helper.rb', line 42

def dest_file_exists?(file)
  dest_file = File.join(destination_root, file)
  File.exist?(dest_file) ? dest_file : nil
end

#empty_directory_with_keep_file(destination, config = {}) ⇒ Object



60
61
62
63
# File 'lib/generators/react_on_rails/generator_helper.rb', line 60

def empty_directory_with_keep_file(destination, config = {})
  empty_directory(destination, config)
  keep_file(destination)
end

#keep_file(destination) ⇒ Object



65
66
67
# File 'lib/generators/react_on_rails/generator_helper.rb', line 65

def keep_file(destination)
  create_file("#{destination}/.keep") unless options[:skip_keeps]
end

#package_jsonObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/generators/react_on_rails/generator_helper.rb', line 7

def package_json
  # Lazy load package_json gem only when actually needed for dependency management

  require "package_json" unless defined?(PackageJson)
  @package_json ||= PackageJson.read
rescue LoadError
  puts "Warning: package_json gem not available. This is expected before Shakapacker installation."
  puts "Dependencies will be installed using the default package manager after Shakapacker setup."
  nil
rescue StandardError => e
  puts "Warning: Could not read package.json: #{e.message}"
  puts "This is normal before Shakapacker creates the package.json file."
  nil
end

#setup_file_error(file, data) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/generators/react_on_rails/generator_helper.rb', line 52

def setup_file_error(file, data)
  <<~MSG
    #{file} was not found.
    Please add the following content to your #{file} file:
    #{data}
  MSG
end

#shakapacker_version_9_or_higher?Boolean

Note:

Default behavior: Returns true when Shakapacker is not yet installed Rationale: During fresh installations, we optimistically assume users will install the latest Shakapacker version. This ensures new projects get best-practice configs. If users later install an older version, the generated webpack config includes fallback logic (e.g., ‘config.privateOutputPath || hardcodedPath`) that prevents breakage, and validation warnings guide them to fix any misconfigurations.

Check if Shakapacker 9.0 or higher is available Returns true if Shakapacker >= 9.0, false otherwise

This method is used during code generation to determine which configuration patterns to use in generated files (e.g., config.privateOutputPath vs hardcoded paths).

Returns:

  • (Boolean)

    true if Shakapacker 9.0+ is available or likely to be installed



113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/generators/react_on_rails/generator_helper.rb', line 113

def shakapacker_version_9_or_higher?
  return @shakapacker_version_9_or_higher if defined?(@shakapacker_version_9_or_higher)

  @shakapacker_version_9_or_higher = begin
    # If Shakapacker is not available yet (fresh install), default to true
    # since we're likely installing the latest version
    return true unless defined?(ReactOnRails::PackerUtils)

    ReactOnRails::PackerUtils.shakapacker_version_requirement_met?("9.0.0")
  rescue StandardError
    # If we can't determine version, assume latest
    true
  end
end

As opposed to Rails::Generators::Testing.create_link, which creates a link pointing to source_root, this symlinks a file in destination_root to a file also in destination_root.



72
73
74
75
76
77
78
79
80
81
# File 'lib/generators/react_on_rails/generator_helper.rb', line 72

def symlink_dest_file_to_dest_file(target, link)
  target_pathname = Pathname.new(File.join(destination_root, target))
  link_pathname = Pathname.new(File.join(destination_root, link))

  link_directory = link_pathname.dirname
  link_basename = link_pathname.basename
  target_relative_path = target_pathname.relative_path_from(link_directory)

  `cd #{link_directory} && ln -s #{target_relative_path} #{link_basename}`
end

#using_swc?Boolean

Note:

This method is used to determine whether to install SWC dependencies (@swc/core, swc-loader) instead of Babel dependencies during generation.

Note:

Caching: The result is memoized for the lifetime of the generator instance. If shakapacker.yml changes during generator execution (unlikely), the cached value will not update. This is acceptable since generators run quickly.

Check if SWC is configured as the JavaScript transpiler in shakapacker.yml

Detection logic:

  1. If shakapacker.yml exists and specifies javascript_transpiler: parse it

  2. For Shakapacker 9.3.0+, SWC is the default if not specified

  3. Returns true for fresh installations (SWC is recommended default)

Returns:

  • (Boolean)

    true if SWC is configured or should be used by default



143
144
145
146
147
# File 'lib/generators/react_on_rails/generator_helper.rb', line 143

def using_swc?
  return @using_swc if defined?(@using_swc)

  @using_swc = detect_swc_configuration
end