Class: Clavis::Generators::InstallGenerator

Inherits:
Rails::Generators::Base
  • Object
show all
Includes:
ActiveRecord::Generators::Migration, Rails::Generators::Actions
Defined in:
lib/generators/clavis/install_generator.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.next_migration_number(dirname) ⇒ Object

Implement the required next_migration_number method Must be defined as a class method



20
21
22
23
# File 'lib/generators/clavis/install_generator.rb', line 20

def self.next_migration_number(dirname)
  next_migration_number = current_migration_number(dirname) + 1
  ActiveRecord::Migration.next_migration_number(next_migration_number)
end

Instance Method Details

#add_stylesheetsObject



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/generators/clavis/install_generator.rb', line 30

def add_stylesheets
  # Create the vendor directory if it doesn't exist
  vendor_css_dir = Rails.root.join("vendor", "assets", "stylesheets")
  FileUtils.mkdir_p(vendor_css_dir) unless File.directory?(vendor_css_dir)

  # Copy the CSS template to the vendor directory
  template "clavis.css", "vendor/assets/stylesheets/clavis.css"
  say_status :create, "vendor/assets/stylesheets/clavis.css", :green

  # Create custom styles file in app/assets
  create_file "app/assets/stylesheets/clavis_custom.css", "/* Add your custom Clavis styles here */"
  say_status :create, "app/assets/stylesheets/clavis_custom.css", :green

  # For Rails 7+ with Propshaft
  if File.exist?(Rails.root.join("app", "assets", "stylesheets", "application.css"))
    app_css_content = File.read(Rails.root.join("app", "assets", "stylesheets", "application.css"))
    if app_css_content.include?("Propshaft")
      # Create a separate file for Propshaft
      propshaft_css_path = Rails.root.join("app", "assets", "stylesheets", "clavis_styles.css")
      create_file propshaft_css_path, File.read(File.expand_path("clavis.css", source_paths.first))
      say_status :create, "app/assets/stylesheets/clavis_styles.css for Propshaft", :green
      @provide_css_instructions = true
      return
    end
  end

  # Different strategies for different asset pipeline setups
  if File.exist?(Rails.root.join("app", "assets", "stylesheets", "application.scss"))
    append_to_file "app/assets/stylesheets/application.scss", "\n@import 'clavis';\n"
    say_status :insert, "clavis import in application.scss", :green
  elsif File.exist?(Rails.root.join("app", "assets", "stylesheets", "application.css"))
    inject_into_file "app/assets/stylesheets/application.css", " *= require clavis\n", before: "*/",
                                                                                       verbose: false
    say_status :insert, "clavis require in application.css", :green
  elsif File.exist?(Rails.root.join("app", "assets", "stylesheets", "application.css.scss"))
    append_to_file "app/assets/stylesheets/application.css.scss", "\n@import 'clavis';\n"
    say_status :insert, "clavis import in application.css.scss", :green
  else
    say_status :warn, "Could not find main application CSS file", :yellow
    create_file "app/assets/stylesheets/clavis_styles.css",
                File.read(File.expand_path("clavis.css", source_paths.first))
    say_status :create, "app/assets/stylesheets/clavis_styles.css as fallback", :green
    @provide_css_instructions = true
  end
end

#create_initializerObject



25
26
27
28
# File 'lib/generators/clavis/install_generator.rb', line 25

def create_initializer
  template "initializer.rb", "config/initializers/clavis.rb"
  say_status :create, "config/initializers/clavis.rb", :green
end

#create_migrationObject



76
77
78
79
80
81
82
83
84
# File 'lib/generators/clavis/install_generator.rb', line 76

def create_migration
  # First, create the OAuth identities table migration if it doesn't exist
  create_identities_migration

  # Then create the User table migration if the users table exists
  create_user_migration
rescue ActiveRecord::NoDatabaseError
  say_status :error, "Skipping migration because database doesn't exist. Run 'rails db:create' first.", :red
end

#create_user_methodObject



100
101
102
103
# File 'lib/generators/clavis/install_generator.rb', line 100

def create_user_method
  # Generate the user method concern
  generate "clavis:user_method"
end

#mount_engineObject



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/generators/clavis/install_generator.rb', line 86

def mount_engine
  # Check if the route already exists in the routes file
  routes_content = File.read(Rails.root.join("config/routes.rb"))

  # Only add the route if it doesn't already exist
  if routes_content.include?("mount Clavis::Engine")
    say_status :skip, "Clavis::Engine is already mounted, skipping route addition.", :yellow
  else
    route "mount Clavis::Engine => '/auth'"
    say_status :route, "Mounted Clavis::Engine at /auth", :green
    say_status :info, "Added auth_path and auth_callback_path route helpers", :green
  end
end

#show_post_install_messageObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/generators/clavis/install_generator.rb', line 105

def show_post_install_message
  say "\nClavis has been installed successfully! 🔑"

  # What was done section
  say "\n=== What Was Done ==="
  say "✅ Generated migration for OAuth identities"
  say "✅ Added OAuth fields to your User model"
  say "✅ Created ClavisUserMethods concern for your User model"
  say "✅ Mounted Clavis engine at '/auth' in routes.rb"
  say "✅ Generated configuration initializer"

  # Required steps section
  say "\n=== Required Steps ==="
  steps = []

  steps << "Run migrations:\n   $ rails db:migrate"
  steps << "Configure your providers in config/initializers/clavis.rb:\n   • Add your client_id and client_secret\n   • Set correct redirect_uri values" # rubocop:disable Layout/LineLength
  steps << "⚠️ IMPORTANT: Customize user creation in app/models/concerns/clavis_user_methods.rb\n   • The default only sets the email field, which is likely insufficient\n   • Add all required fields for your User model" # rubocop:disable Layout/LineLength

  # Output numbered steps
  steps.each_with_index do |step, index|
    say "#{index + 1}. #{step}"
  end

  # Password validation section
  say "\n=== For Password-Protected Users ==="
  say "If your User model uses has_secure_password:"
  say "• Uncomment the password validation section in app/models/concerns/clavis_user_methods.rb"
  say "• Choose one of the approaches described there"

  # View integration section
  say "\n=== Using In Your Views ==="
  say "Add OAuth buttons to your login page:"
  say "<%= clavis_oauth_button :google %>"
  say "<%= clavis_oauth_button :github %>"

  # CSS styling section
  if @provide_css_instructions
    say "\n=== For CSS Styling ==="
    say "Include Clavis styles in your layout:"
    say "<%= stylesheet_link_tag 'clavis_styles' %>"
  end

  say "\nFor more information, see: https://github.com/clayton/clavis"
end