refinerycms 1.0.11 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/refinerycms CHANGED
@@ -1,472 +1,27 @@
1
1
  #!/usr/bin/env ruby
2
- # Load bundler
3
- begin
4
- require 'rubygems'
5
- require 'bundler'
6
- rescue LoadError
7
- puts "\n=== ACTION REQUIRED ===\n\n"
8
- puts "Could not load the bundler gem. This is a required dependency of Refinery CMS."
9
- puts "Please install it with `gem install bundler`.\n\n"
10
- exit(1)
11
- end
12
-
13
- # Let the application have a constant it can detect installation with.
14
- REFINERYCMS_INSTALLER = true
15
- RAILS_MINOR_VERSION = '3.0'
16
-
17
- # Load refinerycms
18
- require File.expand_path(File.dirname(__FILE__) << "/../lib/refinery")
19
-
20
- # Load other required libraries
21
- require 'pathname'
22
- require 'fileutils'
23
- require 'optparse'
24
-
25
- module Refinery
26
- class AppGenerator
27
-
28
- def initialize(input)
29
- # Default options
30
- @input = input
31
- @options = {
32
- :confirm => false,
33
- :database => {
34
- :adapter => 'sqlite3',
35
- :host => 'localhost',
36
- :ident => false,
37
- :password => nil,
38
- :username => 'root',
39
- :skip => false
40
- },
41
- :force => false,
42
- :gems => [],
43
- :heroku => false,
44
- :testing => false,
45
- :rails => {
46
- :version => nil
47
- }
48
- }
49
-
50
- @optparse = OptionParser.new do |opts|
51
- opts.banner = "Purpose: Installs Refinery CMS to the specified directory"
52
- opts.banner << "\nUsage: #{opts.program_name} /path/to/project [options]"
53
-
54
- opts.separator ""
55
- opts.separator "Specific Options:"
56
-
57
- # Bail out if --update is specified.
58
- opts.on('--update') do |update|
59
- puts "\nYou specified --update which is a command that has been removed."
60
- puts "To update your application:"
61
- puts "- Change the version of the 'refinerycms' gem in your Gemfile."
62
- puts "- Run bundle install"
63
- puts "- Run bundle exec rails generate refinerycms --update"
64
- puts "\n"
65
- exit(1)
66
- end
67
-
68
- # Rails supports more options, but Refinery is only tested on these three
69
- databases = %w(mysql postgresql sqlite3)
70
- opts.on("-d DATABASE", "--database DATABASE", databases, "Select the database (default sqlite3)", " #{databases.join('/')}") do |db|
71
- @options[:database][:adapter] = db
72
- end
73
-
74
- opts.on("--ident", "Use ident database authentication (for mysql or postgresql)") do
75
- @options[:database][:ident] = true
76
- end
77
-
78
- opts.on("-u USERNAME", '--database-username USERNAME', String, "Set the database username", ' (default root)') do |username|
79
- @options[:database][:username] = username
80
- end
81
-
82
- opts.on("-p PASSWORD", '--database-password PASSWORD', String, "Set the database password", " (default '')") do |password|
83
- @options[:database][:password] = password
84
- end
85
-
86
- opts.on('-h', '--database-host HOST', String, "Set the database hostname", " (default localhost)") do |host|
87
- @options[:database][:host] = host
88
- end
89
-
90
- opts.on('--skip-db', "Skip any database creation or migration tasks") do
91
- @options[:database][:skip] = true
92
- end
93
-
94
- opts.on("-g", "--gems gem1,gem2,gem3", Array, "Additional gems to install") do |gems|
95
- @options[:gems] = gems.reject {|g| g.to_s =~ /^refinerycms/}.map {|g| "gem '#{g.to_s}'"}
96
- end
97
-
98
- opts.on("-f", "--force", "Force overwriting of directory") do
99
- @options[:force] = true
100
- end
101
-
102
- opts.on("--heroku [APP_NAME]", "Set up and deploy to Heroku") do |app_name|
103
- @options[:heroku] = app_name || ''
104
- end
105
-
106
- opts.on("-c", "--confirm", "Confirm any prompts that require input") do
107
- @options[:confirm] = true
108
- end
109
-
110
- opts.on('-r', "--rails-version VERSION", String, "Override the version of rails used to generate your application.") do |version|
111
- @options[:rails][:version] = version
112
- end
113
-
114
- opts.on('-t', '--testing', "Automatically set up the project with refinerycms-testing support.") do
115
- @options[:testing] = true
116
- end
117
-
118
- opts.separator ""
119
- opts.separator "Common options:"
120
-
121
- opts.on_tail("-h", "--help", "Display this screen") do
122
- puts opts
123
- exit
124
- end
125
-
126
- opts.on_tail("-v", "--version", "Display the version") do
127
- puts Refinery.version
128
- exit
129
- end
130
- end
131
- end
132
-
133
- def run!
134
- # Grab input and ensure that the path doesn't exist already and other checks.
135
- validate!
136
-
137
- # Generate a Refinery CMS application
138
- generate!
139
-
140
- # Bundle the application which activates Refinery CMS
141
- bundle!
142
-
143
- # Run any database migrations
144
- migrate! unless @options[:database][:skip]
145
-
146
- # Deploy to a hosting provider
147
- deploy!
148
-
149
- # Output helpful messages to user
150
- output!
151
- end
152
-
153
- def validate!
154
- # Check for valid input
155
- begin
156
- @optparse.parse!(@input)
157
- rescue OptionParser::ParseError => pe
158
- puts pe
159
- puts "\n"
160
- puts @optparse
161
- exit(1)
162
- end
163
-
164
- # Ensure only one path is specified
165
- unless @input.size == 1
166
- puts "Please specify a single path to install Refinery CMS"
167
- puts "\n"
168
- puts @optparse
169
- exit(1)
170
- end
171
-
172
- # Get the name and path of the new application
173
- @app_path = Pathname.new(File.expand_path(@input.first))
174
- @app_name = @app_path.to_s.split(File::SEPARATOR).last
175
-
176
- rails_version_in_path = run_command('rails --version', {:cd => false, :bundler => false, :puts => false}).to_s.gsub(/(Rails |\n)/, '')
177
- @rails_version_to_use = @options[:rails][:version] || rails_version_in_path
178
- if @rails_version_to_use !~ %r{\b#{RAILS_MINOR_VERSION}}
179
- puts "\nRails #{@rails_version_to_use} is not supported by Refinery #{::Refinery.version}, " \
180
- "please use Rails #{RAILS_MINOR_VERSION}.x instead."
181
- puts "\nYou can tell Refinery CMS an installed and compatible rails version to use like so:\n"
182
- puts "\nrefinerycms #{@app_name} --rails-version #{RAILS_MINOR_VERSION}"
183
- puts "\n"
184
- exit(1)
185
- end
186
-
187
- # Get the refinery path based on this file
188
- @refinery_path = Pathname.new(File.expand_path('../../', __FILE__))
189
-
190
- if @app_path == @refinery_path
191
- puts "\nPlease generate your new project from outside the Refinery directory and any Rails directory."
192
- puts "\n"
193
- exit(1)
194
- elsif %w(refinery refinerycms test testing rails).include?(@input.first.downcase)
195
- puts "\nYou can't use '#{@input.first}' as a name for your project, this is a reserved word that will cause conflicts."
196
- puts "Please choose another name for your new project."
197
- puts "\n"
198
- exit(1)
199
- elsif @app_path.directory? && !@options[:force]
200
- puts "\nThe directory '#{@app_path}' that you specified already exists."
201
- puts "Use --force to overwrite an existing directory."
202
- puts "\n"
203
- exit(1)
204
- elsif @options[:heroku]
205
- if @options[:heroku].to_s.include?('_') or @options[:heroku].to_s.length > 30
206
- message = ["\nThe application name '#{@options[:heroku]}' that you specified is invalid for Heroku."]
207
- suggested_name = @options[:heroku].to_s
208
- if suggested_name.include?('_')
209
- message << "This is because it contains underscores which Heroku does not allow."
210
- suggested_name.gsub!(/_/, '-')
211
- end
212
- if suggested_name.length > 30
213
- message << "This is#{" also" unless suggested_name.nil?} because it is longer than 30 characters."
214
- suggested_name = suggested_name[0..29]
215
- end
216
-
217
- if @options[:force] or @options[:confirm]
218
- @options[:heroku] = suggested_name
219
- else
220
- message << "Please choose another name like '#{suggested_name}'"
221
- message << "Or use --confirm to automatically use '#{suggested_name}'"
222
- message << "\n"
223
- puts message.join("\n")
224
- exit(1)
225
- end
226
- end
227
- end
228
- end
229
-
230
- def generate!
231
- # Generate a rails application
232
- rails_command = "rails _#{@rails_version_to_use}_ new \"#{@app_path}\""
233
- rails_command << " --database #{@options[:database][:adapter]}"
234
- rails_command << " --force" if @options[:force]
235
- rails_command << " --skip-test-unit --skip-prototype"
236
- rails_command << " --skip-bundle" # Rails automatically installs the bundle, but so do we!
237
- rails_command << " -m http://jruby.org" if defined? JRUBY_VERSION
238
-
239
- rails_output = run_command(rails_command, {:cd => false, :bundler => false})
240
-
241
- # Detect non-success or a blank rails output or starting with "Can't initialize" or "Error"
242
- if !$?.success? or rails_output.to_s.length == 0 or rails_output =~ /^(Can't\ initialize|Error)/
243
- puts "\nGenerating Rails application failed. Exiting..."
244
- if run_command('gem list rails', {:cd => false, :puts => false, :ruby => false}) !~ %r{[( ]#{@rails_version_to_use}(.0)*[,\)]}
245
- puts "\nDo you have Rails #{@rails_version_to_use} installed?"
246
- end
247
- puts "\n"
248
- exit(1)
249
- else
250
- if defined? JRUBY_VERSION
251
- find_and_replace(@app_path.join('Gemfile'), /['|"]sqlite3['|"]/, "'activerecord-jdbcsqlite3-adapter'")
252
- end
253
-
254
- # Remove rails from the Gemfile so that Refinery can manage it
255
- find_and_replace('Gemfile', %r{^gem 'rails'}, "# gem 'rails'")
256
-
257
- # Override database host
258
- if @options[:database][:host] != 'localhost' && (adapter = @options[:database][:adapter]) != 'sqlite3'
259
- adapter = 'mysql2' if adapter == 'mysql'
260
- find_and_replace('config/database.yml', "\n adapter: #{adapter}", "\n adapter: #{adapter}\n host: #{@options[:database][:host]}")
261
- end
262
-
263
- # Override database username and password
264
- if @options[:database][:ident]
265
- find_and_replace('config/database.yml', %r{username:}, '#username:')
266
- find_and_replace('config/database.yml', %r{password:}, '#password:')
267
- else
268
- find_and_replace('config/database.yml', %r{username:.*}, "username: #{@options[:database][:username]}")
269
- find_and_replace('config/database.yml', %r{password:.*}, "password: \"#{@options[:database][:password]}\"")
270
- end
271
-
272
- puts "\n---------"
273
- puts "Refinery successfully installed in '#{@app_path}'!\n\n"
274
- end
275
- end
276
-
277
- def bundle!
278
- # Insert the current REFINERY CMS section (you shouldn't put anything in here).
279
- refinery_gemfile_contents = Refinery.root.join('Gemfile').read
280
- refinery_gems = refinery_gemfile_contents.match(/# REFINERY CMS =+.*# END REFINERY CMS =+/m)[0]
281
- refinery_gems.gsub!("# gem 'refinerycms'", "gem 'refinerycms'") # Enable refinerycms
282
- if @options[:testing] # Enable testing
283
- refinery_gems.gsub!("\n=begin #testing", '')
284
- refinery_gems.gsub!("\n=end #testing", '')
285
- end
286
-
287
- app_gemfile = @app_path.join('Gemfile')
288
- refinery_user_defined_gems = refinery_gemfile_contents.match(/# USER DEFINED(.*)# END USER DEFINED/m)
289
- refinery_user_defined_gems = refinery_user_defined_gems[1] unless refinery_user_defined_gems.nil?
290
-
291
- app_gemfile.open('a') do |f|
292
- f.write "\n#{refinery_gems}\n"
293
- @options[:gems] = ([refinery_user_defined_gems] | [@options[:gems]]).flatten.compact
294
-
295
- f.write "\n# USER DEFINED\n#{@options[:gems].join("\n")}\n# END USER DEFINED" if @options[:gems].any?
296
- end
297
-
298
- # Specify the correct version of the Refinery CMS gem (may be git source).
299
- src = Refinery.version !~ /\.pre$/ ? "'~> #{Refinery.version}'" : ":git => 'git://github.com/resolve/refinerycms'"
300
- find_and_replace('Gemfile', %r{gem 'refinerycms',.*}, "gem 'refinerycms', #{src}")
301
-
302
- # Add in fog gem for Heroku
303
- find_and_replace('Gemfile', "# gem 'fog'", "gem 'fog'") if @options[:heroku]
304
-
305
- # Automate
306
- puts "Installing gem requirements using bundler..\n"
307
-
308
- # Install!
309
- run_command("bundle install", {:fail => "Unable to install necessary gems"})
310
- end
311
-
312
- def migrate!
313
- unless @options[:database][:adapter] == 'sqlite3'
314
- # Ensure the database exists so that queries like .table_exists? don't fail.
315
- puts "\nCreating a new database.."
316
-
317
- # Warn about incorrect username or password.
318
- if @options[:database][:ident]
319
- note = "NOTE: If ident authentication fails then the installer will stall or fail here.\n\n"
320
- else
321
- note = "NOTE: if your database username is not '#{@options[:database][:username]}'"
322
- note << " or your password is not '#{@options[:database][:password]}' then the installer will stall here.\n\n"
323
- end
324
- puts note
325
-
326
- run_command("rake -f \"#{@app_path.join('Rakefile')}\" db:create", {
327
- :fail => "Unable to create the application's database",
328
- :bundler => true
329
- })
330
- end
331
-
332
- generators!
333
-
334
- puts "\n\nSetting up your development database..\n"
335
- run_command("rake -f \"#{@app_path.join('Rakefile')}\" db:migrate", :bundler => true)
336
- end
337
-
338
- def generators!
339
- # Run the newly activated Refinery CMS generator.
340
- puts "\n\nPreparing your application using the refinerycms generator..\n"
341
- run_command("rails generate refinerycms", {
342
- :cd => true,
343
- :fail => "Could not run the refinerycms generator successfully.",
344
- :bundler => true
345
- })
346
-
347
- if @options[:testing]
348
- puts "\n\nAdding testing support files using the refinerycms_testing generator..\n"
349
- run_command("rails generate refinerycms_testing", {
350
- :cd => true,
351
- :fail => "Could not run the refinerycms_testing generator successfully.",
352
- :bundler => true
353
- })
354
- end
355
- end
356
-
357
- def deploy!
358
- # Deploy to Heroku
359
- hosting = nil
360
- hosting = "Heroku" if @options[:heroku]
361
- unless hosting.nil?
362
- puts "\n\nInitializing and committing to git..\n"
363
- run_command("git init && git add . && git commit -am 'Initial Commit'", :ruby => false)
364
-
365
- puts "\n\nCreating #{hosting} app..\n"
366
- run_command("#{hosting.downcase} create #{@options[:heroku]}")
367
-
368
- puts "\n\nPushing to #{hosting} (this takes time, be patient)..\n"
369
- run_command("git push #{hosting.downcase} master", :ruby => false)
370
-
371
- puts "\n\nSetting up the #{hosting} database..\n"
372
- run_command("#{hosting.downcase} rake db:migrate")
373
-
374
- if @options[:heroku]
375
- puts "\n\nRestarting servers...\n"
376
- run_command("#{hosting.downcase} restart")
377
- end
378
- end
379
- # End automation
380
- end
381
-
382
- def output!
383
- # Construct helpful output messages
384
- note = ["\n=== ACTION REQUIRED ==="]
385
- if @options[:database][:skip]
386
- note << "Because you elected to skip database creation and migration in the installer"
387
- note << "you will need to run the following tasks manually to maintain correct operation:"
388
- note << "\ncd #{@app_path}"
389
- note << "bundle exec rake db:create"
390
- note << "bundle exec rails generate refinerycms"
391
- note << "bundle exec rake db:migrate"
392
- note << "\n---------\n"
393
- end
394
- note << "Now you can launch your webserver using:"
395
- note << "\ncd #{@app_path}"
396
- note << "rails server"
397
- note << "\nThis will launch the built-in webserver at port 3000."
398
- note << "You can now see your site running in your browser at http://localhost:3000"
399
-
400
- if @options[:heroku]
401
- note << "\nIf you want files and images to work on heroku, you will need setup S3:"
402
- note << "heroku config:add S3_BUCKET=XXXXXXXXX S3_KEY=XXXXXXXXX S3_SECRET=XXXXXXXXXX S3_REGION=XXXXXXXXXX"
403
- end
404
-
405
- note << "\nThanks for installing Refinery, enjoy creating your new application!"
406
- note << "---------\n\n"
407
-
408
- # finally, output.
409
- puts note.join("\n")
410
- end
411
-
412
- private :bundle!, :deploy!, :generate!, :generators!, :migrate!, :output!, :validate!
413
-
414
- def run_command(command, options = {})
415
- require 'rbconfig'
416
- options = {:cd => true, :puts => true, :fail => nil, :ruby => true, :bundler => false}.merge(options)
417
- to_run = %w()
418
- to_run << "cd \"#{@app_path}\" &&" if options[:cd]
419
-
420
- # Sometimes we want to exclude the ruby runtime executable from the front
421
- # e.g. when shelling to git
422
- if options[:ruby]
423
- exe = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['RUBY_INSTALL_NAME'])
424
- to_run << "\"#{exe}\" -S "
425
- end
426
-
427
- to_run << "bundle exec" if options[:bundler]
428
-
429
- to_run << command
430
-
431
- if Refinery::WINDOWS
432
- to_run = ['"'] + to_run + ['"']
433
- to_run = %w(cmd /c) + to_run.map{|c| c.gsub(/\//m, '\\')}
434
- end
435
-
436
- to_run = to_run.join(' ')
437
-
438
- output = []
439
- if options[:puts]
440
- puts "Running: #{to_run}"
441
- IO.popen(to_run) do |t|
442
- while (line = t.gets)
443
- output << line
444
- puts line
445
- end
446
- end
447
- else
448
- output << `#{to_run}`
449
- end
450
-
451
- if $?.success? or options[:fail].nil?
452
- output.join("\n")
453
- else
454
- puts "\nFailed to generate application."
455
- puts "Message: #{options[:fail]}" unless options[:fail].nil?
456
- puts "Exiting...\n\n"
457
- exit(1)
458
- end
459
- end
460
-
461
- def find_and_replace(file, find, replace)
462
- (contents = @app_path.join(file).read).gsub!(find, replace)
463
- (@app_path + file).open("w") do |f|
464
- f.puts contents
465
- end
466
- end
467
-
468
- protected :run_command, :find_and_replace
2
+ gem 'railties'
3
+ require 'rails/generators'
4
+ require 'rails/generators/rails/app/app_generator'
5
+ template_path = File.expand_path('../../templates/refinery/installer.rb', __FILE__)
6
+
7
+ application_name = ARGV.shift
8
+ result = Rails::Generators::AppGenerator.start [application_name, '-m', template_path, '--skip-test-unit'] | ARGV
9
+
10
+ if result && result.include?('Gemfile')
11
+ note = ["\n=== ACTION REQUIRED ==="]
12
+ note << "Now you can launch your webserver using:"
13
+ note << "\ncd #{application_name}"
14
+ note << "rails server"
15
+ note << "\nThis will launch the built-in webserver at port 3000."
16
+ note << "You can now see your site running in your browser at http://localhost:3000"
17
+
18
+ if ARGV.include?('--heroku')
19
+ note << "\nIf you want files and images to work on Heroku, you will need setup S3:"
20
+ note << "heroku config:add S3_BUCKET=XXXXXXXXX S3_KEY=XXXXXXXXX S3_SECRET=XXXXXXXXXX S3_REGION=XXXXXXXXXX"
469
21
  end
470
- end
471
22
 
472
- Refinery::AppGenerator.new(ARGV).run! if $0 =~ %r{refinerycms$}
23
+ note << "\nThanks for installing Refinery CMS, we hope you enjoy crafting your application!"
24
+ note << "---------\n\n"
25
+
26
+ puts note
27
+ end