1 require 'rbconfig'
2
3 # Small addition to enable the enqueing of "bundle install"
4 class Rails::Generator::Commands::Create
5 def run_bundler(destination_root)
6 # thanks to http://spectator.in/2011/01/28/bundler-in-subshells/
7 bundler_vars = %w(BUNDLE_GEMFILE RUBYOPT )
8 command = %{"#{Gem.ruby}" -rubygems "#{Gem.bin_path('bundler', 'bundle')}" install --gemfile="#{File.join(File.expand_path(destination_root), 'Gemfile')}"}
9 begin
10 bundled_env = ENV.to_hash
11 bundler_vars.each{ |var| ENV.delete(var) }
12 print `#{command}`
13 ensure
14 ENV.replace(bundled_env)
15 end
16 end
17 end
18
19 class InstanceGenerator < Rails::Generator::Base
20 DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
21 Config::CONFIG['ruby_install_name'])
22
23 DATABASES = %w( mysql postgresql sqlite3 sqlserver db2 )
24
25 MYSQL_SOCKET_LOCATIONS = [
26 "/tmp/mysql.sock", # default
27 "/var/run/mysqld/mysqld.sock", # debian/gentoo
28 "/var/tmp/mysql.sock", # freebsd
29 "/var/lib/mysql/mysql.sock", # fedora
30 "/opt/local/lib/mysql/mysql.sock", # fedora
31 "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
32 "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
33 "/opt/local/var/run/mysql5/mysqld.sock" # mac + darwinports + mysql5
34 ]
35
36 default_options :db => "sqlite3", :shebang => DEFAULT_SHEBANG, :freeze => false
37
38 def initialize(runtime_args, runtime_options = {})
39 super
40 usage if args.empty?
41 usage("Databases supported for preconfiguration are: #{DATABASES.join(", ")}") if (options[:db] && !DATABASES.include?(options[:db]))
42 @destination_root = args.shift
43 end
44
45 def manifest
46 # The absolute location of the Radiant files
47 root = File.expand_path(RADIANT_ROOT)
48
49 # Use /usr/bin/env if no special shebang was specified
50 script_options = { :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang] }
51 dispatcher_options = { :chmod => 0755, :shebang => options[:shebang] }
52
53 record do |m|
54 # Root directory
55 m.directory ""
56
57 # Standard files and directories
58 base_dirs = %w(config config/environments config/initializers db log script public vendor/plugins vendor/extensions)
59 text_files = %w(CHANGELOG.md CONTRIBUTORS.md LICENSE.md INSTALL.md README.md)
60 environments = Dir["#{root}/config/environments/*.rb"]
61 bundler_compatibility_files = %w{config/preinitializer.rb}
62 schema_file = %w{db/schema.rb}
63 scripts = Dir["#{root}/script/**/*"].reject { |f| f =~ /(destroy|generate|plugin)$/ }
64 public_files = ["public/.htaccess"] + Dir["#{root}/public/**/*"]
65 test_files = ["config/cucumber.yml"]
66
67 files = base_dirs + text_files + environments + bundler_compatibility_files + schema_file + scripts + public_files + test_files
68 files.map! { |f| f = $1 if f =~ %r{^#{root}/(.+)$}; f }
69 files.sort!
70
71 files.each do |file|
72 case
73 when File.directory?("#{root}/#{file}")
74 m.directory file
75 when file =~ %r{^script/}
76 m.file radiant_root(file), file, script_options
77 when file =~ %r{^public/dispatch}
78 m.file radiant_root(file), file, dispatcher_options
79 else
80 m.file radiant_root(file), file
81 end
82 end
83
84 # script/generate
85 m.file "instance_generate", "script/generate", script_options
86
87 # database.yml and .htaccess
88 m.template "databases/#{options[:db]}.yml", "config/database.yml", :assigns => {
89 :app_name => File.basename(File.expand_path(@destination_root)),
90 :socket => options[:db] == "mysql" ? mysql_socket_location : nil
91 }
92
93 # Instance Gemfile
94 m.template "instance_gemfile", "Gemfile", :assigns => {
95 :radiant_version => Radiant::Version.to_s,
96 :db => options[:db]
97 }
98
99 # Instance Rakefile
100 m.file "instance_rakefile", "Rakefile"
101
102 # Config.ru is useful in rack-based situations like Pow
103 m.file "instance_config.ru", "config.ru"
104
105 # Instance Configurations
106 m.file "instance_routes.rb", "config/routes.rb"
107 m.template "instance_environment.rb", "config/environment.rb", :assigns => {
108 :radiant_environment => File.join(File.dirname(__FILE__), 'templates', radiant_root("config/environment.rb")),
109 :app_name => File.basename(File.expand_path(@destination_root))
110 }
111 m.template "instance_boot.rb", "config/boot.rb"
112 m.file "instance_radiant_config.rb", "config/initializers/radiant_config.rb"
113
114 # Run bundler
115 m.run_bundler @destination_root
116
117 m.readme radiant_root("INSTALL.md")
118 end
119 end
120
121 protected
122
123 def banner
124 "Usage: #{$0} /path/to/radiant/app [options]"
125 end
126
127 def add_options!(opt)
128 opt.separator ''
129 opt.separator 'Options:'
130 opt.on("-r", "--ruby=path", String,
131 "Path to the Ruby binary of your choice (otherwise scripts use env, dispatchers current path).",
132 "Default: #{DEFAULT_SHEBANG}") { |v| options[:shebang] = v }
133 opt.on("-d", "--database=name", String,
134 "Preconfigure for selected database (options: #{DATABASES.join(", ")}).",
135 "Default: sqlite3") { |v| options[:db] = v }
136 end
137
138 def mysql_socket_location
139 RUBY_PLATFORM =~ /mswin32/ ? MYSQL_SOCKET_LOCATIONS.find { |f| File.exists?(f) } : nil
140 end
141
142 private
143
144 def radiant_root(filename = '')
145 File.join("..", "..", "..", "..", filename)
146 end
147
148 end