magicmonkey 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 pioz
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = magic_monkey
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 pioz. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "magicmonkey"
8
+ gem.version = File.exist?('VERSION') ? File.read('VERSION').strip : ''
9
+ gem.summary = %Q{Manage your Rails applications: different Ruby versions and different application servers}
10
+ gem.description = %Q{Manage your Rails applications: different Ruby versions and different application servers}
11
+ gem.email = "enrico@megiston.it"
12
+ gem.homepage = "http://github.com/pioz/magicmonkey"
13
+ gem.authors = ["pioz"]
14
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
15
+ #gem.add_dependency 'nokogiri'
16
+ #gem.add_dependency 'activerecord'
17
+ #gem.add_dependency 'sqlite3-ruby'
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/test_*.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/test_*.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+ task :test => :check_dependencies
45
+
46
+ task :default => :test
47
+
48
+ require 'rake/rdoctask'
49
+ Rake::RDocTask.new do |rdoc|
50
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "magicmonkey #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.10
data/bin/magicmonkey ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $APP_PATH = "#{File.dirname(__FILE__)}/.."
4
+ require "#{$APP_PATH}/lib/magic_monkey.rb"
5
+
6
+ MagicMonkey.main(ARGV)
@@ -0,0 +1,68 @@
1
+ require 'singleton'
2
+ require 'yaml'
3
+
4
+ class Conf
5
+ include Singleton
6
+ attr_reader :config
7
+
8
+ def initialize
9
+ load
10
+ end
11
+
12
+ def load
13
+ @file = "#{Etc.getpwuid.dir}/.magicmonkey.yml"
14
+ if File.exist?(@file)
15
+ @config = YAML.load_file(@file)
16
+ else
17
+ vht = ""
18
+ vht << "<VirtualHost tagi:80>\n"
19
+ vht << " ServerName $SERVER_NAME\n"
20
+ vht << " PassengerEnabled off\n"
21
+ vht << " ProxyPass / http://127.0.0.1:$PORT/\n"
22
+ vht << " ProxyPassReverse / http://127.0.0.1:$PORT/\n"
23
+ vht << "</VirtualHost>\n"
24
+ @config = {:vhost_template => vht}
25
+ self.save
26
+ end
27
+ end
28
+
29
+ def save
30
+ File.open(@file, 'w') { |f| f.write(@config.to_yaml) }
31
+ self.load
32
+ end
33
+
34
+ def self.[](key)
35
+ Conf.instance.config[key.to_sym]
36
+ end
37
+
38
+ def self.[]=(key, value)
39
+ Conf.instance.config[key.to_sym] = value
40
+ end
41
+
42
+ def self.delete(key)
43
+ Conf.instance.config.delete(key.to_sym)
44
+ end
45
+
46
+ def self.save
47
+ Conf.instance.save
48
+ end
49
+
50
+ def self.applications
51
+ app = {}
52
+ Conf.instance.config.each do |k, v|
53
+ if k != :vhost_template && k != :uid
54
+ app[k] = v
55
+ end
56
+ end
57
+ return app
58
+ end
59
+
60
+ def self.ports
61
+ p = []
62
+ Conf.instance.config.each do |k, v|
63
+ p << v[:port] if v.class == Hash && v[:port]
64
+ end
65
+ return p
66
+ end
67
+
68
+ end
@@ -0,0 +1,277 @@
1
+ require 'optparse'
2
+ require 'pp'
3
+ require 'etc'
4
+ require "#{$APP_PATH}/lib/configuration"
5
+
6
+ module MagicMonkey
7
+ COMMANDS = [:start, :stop, :restart, :add, :remove, :show]
8
+
9
+ def self.main(argv)
10
+ raise 'You cannot do this as root' if Process.uid == 0
11
+ Process::UID.change_privilege(Conf[:uid] || Process.uid)
12
+ command = argv[0]
13
+ if command == '-v' || command == '--version'
14
+ puts File.exist?("#{$APP_PATH}/VERSION") ? File.read("#{$APP_PATH}/VERSION").strip : ''
15
+ exit
16
+ elsif command.nil? || command == '-h' || command == '--help' || !COMMANDS.include?(command.to_sym)
17
+ main_help
18
+ exit
19
+ else
20
+ send(command, argv[1..-1])
21
+ end
22
+ end
23
+
24
+ def self.main_help
25
+ puts 'Description here'
26
+ puts
27
+ puts 'Available commands:'
28
+ puts
29
+ COMMANDS.each do |c|
30
+ puts " magicmonkey #{c}\t\tdesc"
31
+ end
32
+ puts
33
+ puts "Special options:"
34
+ puts
35
+ puts " magicmonkey --help\t\tDisplay this help message."
36
+ puts " magicmonkey --version\t\tDisplay version number."
37
+ puts
38
+ puts "For more information about a specific command, please type"
39
+ puts "'magicmonkey <COMMAND> --help', e.g. 'magicmonkey add --help'."
40
+ end
41
+
42
+ def self.show(argv)
43
+ applications = argv
44
+ applications = Conf.applications.keys if argv.empty?
45
+ applications.each do |app_name|
46
+ if Conf[app_name]
47
+ puts app_name
48
+ puts '-'*app_name.to_s.size
49
+ pp Conf[app_name]
50
+ puts
51
+ else
52
+ puts "Application '#{app_name}' not found."
53
+ end
54
+ end
55
+ end
56
+
57
+ def self.start(argv)
58
+ v, help = common_options(argv)
59
+ if help
60
+ puts 'Start a web application added with ADD command. If no params are given start all web applications.'
61
+ exit
62
+ end
63
+ applications = argv
64
+ applications = Conf.applications.keys if argv.empty?
65
+ applications.each do |app_name|
66
+ if Conf[app_name]
67
+ commands = []
68
+ commands << "source '#{Etc.getpwuid.dir}/.rvm/scripts/rvm'"
69
+ commands << "cd '#{Conf[app_name][:app_path]}'"
70
+ commands << "rvm #{v ? 'use ' : ''}'#{Conf[app_name][:ruby]}'"
71
+ case Conf[app_name][:app_server]
72
+ when 'passenger'
73
+ commands << "passenger start -e production -p #{Conf[app_name][:port]} #{Conf[app_name][:app_server_options]} -d"
74
+ when 'thin'
75
+ commands << "thin start -e production -p #{Conf[app_name][:port]} -d"
76
+ end
77
+ print "Starting '#{app_name}' application..."
78
+ STDOUT.flush
79
+ output = `bash -c "#{commands.join(' && ')}"`
80
+ puts ' done.'
81
+ print output if v
82
+ end
83
+ end
84
+ end
85
+
86
+ def self.stop(argv)
87
+ v, help = common_options(argv)
88
+ if help
89
+ puts 'Stop a web application added with ADD command. If no params are given stop all web applications.'
90
+ exit
91
+ end
92
+ applications = argv
93
+ applications = Conf.applications.keys if argv.empty?
94
+ applications.each do |app_name|
95
+ if Conf[app_name]
96
+ commands = []
97
+ commands << "source '#{Etc.getpwuid.dir}/.rvm/scripts/rvm'"
98
+ commands << "cd '#{Conf[app_name][:app_path]}'"
99
+ commands << "rvm #{v ? 'use ' : ''}'#{Conf[app_name][:ruby]}'"
100
+ case Conf[app_name][:app_server]
101
+ when 'passenger'
102
+ commands << "passenger stop -p #{Conf[app_name][:port]}"
103
+ when 'thin'
104
+ commands << "thin stop -p #{Conf[app_name][:port]}"
105
+ end
106
+ print "Stopping '#{app_name}' application..."
107
+ STDOUT.flush
108
+ output = `bash -c "#{commands.join(' && ')}"`
109
+ puts ' done.'
110
+ print output if v
111
+ end
112
+ end
113
+ end
114
+
115
+ def self.restart(argv)
116
+ applications = argv
117
+ applications = Conf.applications.keys if argv.empty?
118
+ applications.each do |app_name|
119
+ self.stop([app_name])
120
+ self.start([app_name])
121
+ end
122
+ end
123
+
124
+ def self.add(argv)
125
+ options = {}
126
+ tmp = argv.join('$$').split(/\$\$--\$\$/)
127
+ argv = tmp[0].split('$$')
128
+ options[:app_server_options] = tmp[1] ? tmp[1].split('$$').join(' ') : ''
129
+ servers = ['passenger', 'thin']
130
+ ports = (3000..4000).to_a.collect{|p| p.to_s}
131
+ rubies = ['default', '1.9.2', '1.8.7', 'ree']
132
+ options[:app_server] = servers.first
133
+ options[:app_path] = '/var/sites/APP_NAME/current'
134
+ options[:port] = nil
135
+ options[:ruby] = rubies.first
136
+ options[:vhost_path] = '/etc/apache2/sites-available'
137
+ vhost_template = "#{Etc.getpwuid.dir}/.magicmonkey.yml"
138
+ force = false
139
+ create_vhost = true
140
+ enable_site = true
141
+ reload_apache = false
142
+ server_name = nil
143
+
144
+ parser = OptionParser.new do |opts|
145
+ opts.banner = 'Usage: magicmonkey add APP_NAME [options] [-- application_server_options]'
146
+ opts.separator ''
147
+ opts.separator 'Options:'
148
+
149
+ opts.on('-s', '--app-server APP_SERVER', servers, "Use the given application server: #{servers.join(', ')} (default: #{options[:app_server]}).") do |s|
150
+ options[:app_server] = s
151
+ end
152
+ opts.on('--app-path APP_PATH', "Use the given application path (default: '#{options[:app_path]}').") do |path|
153
+ options[:app_path] = path
154
+ end
155
+ opts.on('--vhost-path VHOST_PATH', "Use the given virtual host path (default: '#{options[:vhost_path]}').") do |path|
156
+ options[:vhost_path] = path
157
+ end
158
+ opts.on('--vhost-template TEMPLATE', "Use the given virtual host template file (default: #{vhost_template}).") do |template|
159
+ vhost_template = template
160
+ end
161
+ opts.on('-p', '--port NUMBER', ports, "Use the given port number (min: #{ports.first}, max: #{ports.last}).") do |p|
162
+ options[:port] = p.to_i
163
+ end
164
+ opts.on('-r', '--ruby RUBY_VERSION', rubies, "Use the given Ruby version: #{rubies.join(', ')} (default: #{options[:ruby]}).") do |r|
165
+ options[:ruby] = r
166
+ end
167
+ opts.on('-f', '--[no-]force', "Force mode: replace exist files (default: #{force}).") do |f|
168
+ force = f
169
+ end
170
+ opts.on('--[no-]create-vhost', "Create virtual host file from template (default: #{create_vhost}).") do |c|
171
+ create_vhost = c
172
+ end
173
+ opts.on('--[no-]enable-site', "Enable Apache virtual host (default: #{enable_site}).") do |e|
174
+ enable_site = e
175
+ end
176
+ opts.on('--[no-]reload-apache', "Reload apache to load virtual host (default: #{reload_apache}).") do |r|
177
+ reload_apache = r
178
+ end
179
+ opts.on('--server-name SERVER_NAME', "Set ServerName on virtual host (default: APP_NAME).") do |name|
180
+ server_name = name
181
+ end
182
+ opts.on_tail('-h', '--help', 'Show this help message.') do
183
+ puts opts
184
+ exit
185
+ end
186
+ end
187
+ begin
188
+ argv = parser.parse!(argv)
189
+ rescue
190
+ puts parser.help
191
+ exit
192
+ end
193
+ if argv.size != 1
194
+ puts parser.help
195
+ exit
196
+ end
197
+ app_name = argv[0]
198
+ #setting up default values
199
+ options[:app_path].gsub!('APP_NAME', app_name)
200
+ port = get_port(options[:port])
201
+ if port
202
+ options[:port] = port
203
+ else
204
+ puts 'This port is busy'
205
+ exit
206
+ end
207
+ #start
208
+ if Conf[app_name].nil?
209
+ Conf[app_name] = options
210
+ puts "Configuration for application '#{app_name}' is:"
211
+ pp Conf[app_name]
212
+ print 'Add this application? [Y/n]'
213
+ input = STDIN.gets
214
+ if input.upcase == "Y\n" || input == "\n"
215
+ if create_vhost
216
+ vh = YAML.load_file(vhost_template)[:vhost_template]
217
+ vh.gsub!('$SERVER_NAME', server_name || app_name)
218
+ #vh.gsub!('$DOCUMENT_ROOT', Conf[app_name][:app_path])
219
+ vh.gsub!('$PORT', Conf[app_name][:port].to_s)
220
+ vh_file = "#{Conf[app_name][:vhost_path]}/#{app_name}"
221
+ if !File.exist?(vh_file) || force
222
+ #File.open(vh_file, 'w') { |f| f.write(vh) }
223
+ print `sudo bash -c "echo '#{vh}' > #{vh_file}"`
224
+ else
225
+ puts "Virtual host file '#{vh_file}' already exist. Use option '-f' to replace it."
226
+ exit
227
+ end
228
+ print `sudo a2ensite '#{app_name}'` if enable_site
229
+ print `sudo /etc/init.d/apache2 reload` if enable_site && reload_apache
230
+ end
231
+ Conf.save
232
+ puts 'Application added.'
233
+ else
234
+ puts 'Application rejected.'
235
+ end
236
+ else
237
+ puts "Application '#{app_name}' already added. You can remove it with 'remove' command."
238
+ end
239
+ end
240
+
241
+ def self.remove(argv)
242
+ argv.each do |app_name|
243
+ if Conf[app_name]
244
+ vh_file = "#{Conf[app_name][:vhost_path]}/#{app_name}"
245
+ if File.exist?(vh_file)
246
+ print `sudo a2dissite '#{app_name}'`
247
+ print `sudo rm -f #{vh_file}`
248
+ end
249
+ Conf.delete(app_name)
250
+ Conf.save
251
+ else
252
+ puts "Application '#{app_name}' does not exist. You can add it with 'add' command."
253
+ end
254
+ end
255
+ end
256
+
257
+ private
258
+
259
+ def self.get_port(port)
260
+ ports = Conf.ports
261
+ return 3000 if ports.nil? || ports.empty?
262
+ return false if ports.include?(port)
263
+ return ports.max + 1 if port.nil?
264
+ return port
265
+ end
266
+
267
+ def self.common_options(argv)
268
+ verbose = argv.include?('-v') || argv.include?('--version')
269
+ help = argv.include?('-h') || argv.include?('--help')
270
+ argv.delete('-v')
271
+ argv.delete('--version')
272
+ argv.delete('-h')
273
+ argv.delete('--help')
274
+ return verbose, help
275
+ end
276
+
277
+ end
@@ -0,0 +1,57 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{magicmonkey}
8
+ s.version = "0.0.10"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["pioz"]
12
+ s.date = %q{2010-10-28}
13
+ s.default_executable = %q{magicmonkey}
14
+ s.description = %q{Manage your Rails applications: different Ruby versions and different application servers}
15
+ s.email = %q{enrico@megiston.it}
16
+ s.executables = ["magicmonkey"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".gitignore",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "bin/magicmonkey",
28
+ "lib/configuration.rb",
29
+ "lib/magic_monkey.rb",
30
+ "magicmonkey.gemspec",
31
+ "test/helper.rb",
32
+ "test/test_magic_monkey.rb"
33
+ ]
34
+ s.homepage = %q{http://github.com/pioz/magicmonkey}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.7}
38
+ s.summary = %q{Manage your Rails applications: different Ruby versions and different application servers}
39
+ s.test_files = [
40
+ "test/helper.rb",
41
+ "test/test_magic_monkey.rb"
42
+ ]
43
+
44
+ if s.respond_to? :specification_version then
45
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
46
+ s.specification_version = 3
47
+
48
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
50
+ else
51
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
52
+ end
53
+ else
54
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
55
+ end
56
+ end
57
+
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'magic_monkey'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestMagicMonkey < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: magicmonkey
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 10
9
+ version: 0.0.10
10
+ platform: ruby
11
+ authors:
12
+ - pioz
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-28 00:00:00 +02:00
18
+ default_executable: magicmonkey
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: thoughtbot-shoulda
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :development
32
+ version_requirements: *id001
33
+ description: "Manage your Rails applications: different Ruby versions and different application servers"
34
+ email: enrico@megiston.it
35
+ executables:
36
+ - magicmonkey
37
+ extensions: []
38
+
39
+ extra_rdoc_files:
40
+ - LICENSE
41
+ - README.rdoc
42
+ files:
43
+ - .gitignore
44
+ - LICENSE
45
+ - README.rdoc
46
+ - Rakefile
47
+ - VERSION
48
+ - bin/magicmonkey
49
+ - lib/configuration.rb
50
+ - lib/magic_monkey.rb
51
+ - magicmonkey.gemspec
52
+ - test/helper.rb
53
+ - test/test_magic_monkey.rb
54
+ has_rdoc: true
55
+ homepage: http://github.com/pioz/magicmonkey
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options:
60
+ - --charset=UTF-8
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.3.7
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: "Manage your Rails applications: different Ruby versions and different application servers"
86
+ test_files:
87
+ - test/helper.rb
88
+ - test/test_magic_monkey.rb