Class: Storytime::CLI::Install

Inherits:
Object
  • Object
show all
Extended by:
Thor::Actions, Thor::Shell
Defined in:
lib/storytime/cli/install.rb

Class Method Summary collapse

Class Method Details

.add_storytime_mountObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/storytime/cli/install.rb', line 79

def add_storytime_mount
  self.destination_root = File.expand_path("./")
  
  say "Setting up Storytime engine mount point...", :cyan
  mount_point = ask "Where would you like to mount Storytime within the host app? (/)", :yellow

  if mount_point.blank?
    mount_point = "/"
  elsif mount_point[0] != "/" 
    mount_point.prepend("/")
  end

  inject_storytime_mount(mount_point)

  say "Storytime mount point added to routes file\n\n", :green

  return mount_point
end

.add_storytime_user(user_class) ⇒ Object



220
221
222
223
224
225
226
227
228
# File 'lib/storytime/cli/install.rb', line 220

def add_storytime_user(user_class)
  self.destination_root = File.expand_path("./")

  say "Adding `storytime_user` to #{user_class} class...", :cyan

  inject_into_file "app/models/#{user_class.underscore}.rb", "\n  storytime_user\n", :before => /^end/

  say "`storytime_user` added to #{user_class} class.\n\n", :green
end

.automatedObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/storytime/cli/install.rb', line 29

def automated
  defaults = storytime_defaults
  self.destination_root = File.expand_path("./")

  say "Starting install of Storytime...", :cyan

  say "Setting up Storytime engine mount point...", :cyan
  inject_storytime_mount("/")
  say "Storytime mount point added to routes file\n\n", :green

  say "Setting up Storytime initializer file...", :cyan
  Storytime::Generators::Initializer.start [storytime_defaults]
  say "Finished setting up Storytime initializer.\n\n", :green

  check_user_model(defaults[:user_class])
  add_storytime_user(defaults[:user_class])
  copy_migrations
  migrate_db
  copy_views

  say "Finished installing Storytime.", :green
  say "Start up your Rails server and navigate to http://localhost:3000#{defaults[:mount_point]} to use Storytime.", :green
end

.check_user_model(user_class) ⇒ Object



206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/storytime/cli/install.rb', line 206

def check_user_model(user_class)
  unless File.exist?("app/models/#{user_class.underscore}.rb")
    unless File.exist?("config/initializers/devise.rb")
      say "Devise initializer not found... trying to generate one.", :red

      `bin/rails generate devise:install`
    end
    
    say "No #{user_class} model was found... creating one using Devise.", :red

    `bin/rails generate devise #{user_class}`
  end
end

.copy_migrationsObject



230
231
232
233
234
235
236
# File 'lib/storytime/cli/install.rb', line 230

def copy_migrations
  say "Copying over Storytime migrations...", :cyan

  `bin/rake storytime:install:migrations`

  say "Finished copying Storytime migrations.\n\n", :green
end

.copy_viewsObject



246
247
248
249
250
251
252
# File 'lib/storytime/cli/install.rb', line 246

def copy_views
  say "Copying Storytime views...", :cyan

  `bin/rails generate storytime:views`

  say "Finished copying Storytime views.\n\n", :green
end

.inject_storytime_mount(mount_point) ⇒ Object



53
54
55
# File 'lib/storytime/cli/install.rb', line 53

def inject_storytime_mount(mount_point)
  inject_into_file "config/routes.rb", "\n  mount Storytime::Engine => '#{mount_point}'\n", :before => /^end/
end

.interactiveObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/storytime/cli/install.rb', line 57

def interactive
  begin
    require File.expand_path('config/environment.rb')
  rescue LoadError
    say "This command must be run from the root directory of a Rails app... Change directories and try again.", :red
    return
  end

  say "Starting install of Storytime...", :cyan

  mount_point = add_storytime_mount
  init_hash = setup_initializer_file(mount_point)
  check_user_model(init_hash[:user_class])
  add_storytime_user(init_hash[:user_class])
  copy_migrations
  migrate_db unless no? "Would you like to migrate your database now? [y/n] (y)", :yellow
  copy_views unless no? "Would you like to copy Storytime's views to your host app? [y/n] (y)", :yellow

  say "Finished installing Storytime.", :green
  say "Start up your Rails server and navigate to http://localhost:3000#{mount_point} to use Storytime.", :green
end

.migrate_dbObject



238
239
240
241
242
243
244
# File 'lib/storytime/cli/install.rb', line 238

def migrate_db
  say "Running database migrations...", :cyan

  `bin/rake db:migrate`

  say "Finished running database migrations.\n\n", :green
end

.optionsObject



8
# File 'lib/storytime/cli/install.rb', line 8

def options; {}; end

.setup_initializer_file(mount_point) ⇒ Object



98
99
100
101
102
103
104
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/storytime/cli/install.rb', line 98

def setup_initializer_file(mount_point)
  init_hash = storytime_defaults

  say "Setting up Storytime initializer file...", :cyan

  # User Class
  user_class = ask "Name of the model that you want to use for Storytime users? (User)", :yellow

  unless user_class.blank?
    init_hash[:user_class] = user_class.camelize
    init_hash[:enable_user_class] = true
  end

  # Dashboard Namespace Path
  if no? "Do you want to use /storytime as the location of the dashboard? [y/n] (y)", :yellow
    dashboard_namespace_path = ask "Path of Storytime's dashboard, relative to Storytime's mount point, #{mount_point}, within the host app? (/storytime)", :yellow

    init_hash[:dashboard_namespace_path] = dashboard_namespace_path unless dashboard_namespace_path.blank?
    init_hash[:enable_dashboard_namespace_path] = true
  end
  
  # Custom Post Types
  if yes? "Do you want to use additional post types other than Storytime::Page and Storytime::BlogPost? [y/n] (n)", :yellow
    post_types = ask "Enter a comma separated list of additional post types that you'd like to use:", :yellow

    unless post_types.blank?
      post_types = post_types.gsub(",", " ")

      init_hash[:post_types] = "%w(#{post_types})"
      init_hash[:enable_post_types] = true
    end
  end
  
  # Post Title Character Limit
  post_title_character_limit = ask "What should the character limit be for post titles? (100)", :yellow

  if post_title_character_limit.to_i > 0
    if post_title_character_limit.to_i > 255
      say "Character limit amount exceeds database maximum - setting limit to default/maximum amount (255).", :red
      init_hash[:post_title_character_limit] = 255
    else
      init_hash[:post_title_character_limit] = post_title_character_limit.to_i
    end
    
    init_hash[:enable_post_title_character_limit] = true
  elsif !post_title_character_limit.blank?
    say "Character limit amount is not a valid integer... using the default value (255)", :red
  end
  
  # Post Excerpt Character Limit
  post_excerpt_character_limit = ask "What should the character limit be for post excerpts? (500)", :yellow

  if post_excerpt_character_limit.to_i > 0
    init_hash[:post_excerpt_character_limit] = post_excerpt_character_limit.to_i
    init_hash[:enable_post_excerpt_character_limit] = true
  elsif !post_excerpt_character_limit.blank?
    say "Character limit amount is not a valid integer... using the default value (500) instead.", :red
  end

  # Search Adapters
  app_database = ask "What database is being used to run this application?", :yellow, :limited_to => ["mysql", "postgres", "sqlite3", "other"]
  
  if app_database == "other"
    say "Note: This app will not be able to use Storytime's search feature.", :red
  else
    init_hash[:enable_search_adapter] = true
  end

  if app_database == "mysql"
    if yes? "Does this version support Full-Text search (MySql v5.6.4+)? [y/n] (n)", :yellow
      init_hash[:search_adapter] = Storytime::MysqlFulltextSearchAdapter
    else
      init_hash[:search_adapter] = Storytime::MysqlSearchAdapter
    end
  elsif app_database == "postgres"
    init_hash[:search_adapter] = Storytime::PostgresSearchAdapter
  elsif app_database == "sqlite3"
    init_hash[:search_adapter] = Storytime::Sqlite3SearchAdapter
  end

  # Enable File Upload
  unless no? "Do you want to enable file uploads? [y/n] (y)", :yellow
    init_hash[:enable_file_upload] = true

    prod_media_storage = ask "What type of storage do you want to use for production environments?", :yellow, :limited_to => [":file", ":s3"]
    init_hash[:prod_media_storage] = prod_media_storage

    if prod_media_storage == ":s3"
      s3_bucket = ask "What's the name of your S3 bucket?", :yellow
      
      if s3_bucket.blank?
        say "No S3 bucket was listed... using default (my-s3-bucket) instead. Forgetting to change this before deploying to your production environment WILL result in broken uploads.", :red
      else
        init_hash[:s3_bucket] = s3_bucket
      end
    end
  else
    init_hash[:prod_media_storage] = ":file"
    init_hash[:enable_file_upload] = false
  end
  
  Storytime::Generators::Initializer.start [init_hash]

  say "Finished setting up Storytime initializer.\n\n", :green

  return init_hash
end

.storytime_defaultsObject



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/storytime/cli/install.rb', line 10

def storytime_defaults
  hash = {}
  hash[:user_class] = 'User'
  hash[:dashboard_namespace_path] = '/storytime'
  hash[:post_types] = ['CustomPostType']
  hash[:post_title_character_limit] = 100
  hash[:post_excerpt_character_limit] = 500
  hash[:email_regexp] = '/\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/'
  hash[:search_adapter] = "''"
  hash[:enable_file_upload] = true
  hash[:aws_region] = "ENV['STORYTIME_AWS_REGION']"
  hash[:aws_access_key_id] = "ENV['STORYTIME_AWS_ACCESS_KEY_ID']"
  hash[:aws_secret_key] = "ENV['STORYTIME_AWS_SECRET_KEY']"
  hash[:s3_bucket] = 'my-s3-bucket'
  hash[:prod_media_storage] = ':s3'
  hash[:dev_media_storage] = ':file'
  hash
end