rconf 0.10.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,6 +1,6 @@
1
1
  tags
2
2
  pkg/*
3
- .rvmrc
3
+ .ruby-version
4
4
  Gemfile.lock
5
5
  .idea/
6
6
  *.swp
data/CHANGES ADDED
@@ -0,0 +1,5 @@
1
+ === 0.10.2
2
+
3
+ - Download RVM directly from GitHub instead of shunting through rvm.io
4
+ - Allow user to specify nil gemset (e.g. to override project setting)
5
+ - Don't get fooled by an rconf that is on our path but not in our active gemset
data/Gemfile CHANGED
@@ -1,7 +1,10 @@
1
- source :gemcutter
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'rake', ' ~> 0.8.7'
2
5
 
3
6
  #Gems needed to execute the unit specs.
4
- group :test do
7
+ group :development do
5
8
  gem 'rspec', '~> 2.5'
6
9
  gem 'flexmock', '~> 0.9'
7
10
  end
data/README.rdoc CHANGED
@@ -7,7 +7,7 @@
7
7
  As RightScale systems evolve, developers are faced with having to maintain a
8
8
  quickly growing list of applications. Each application requires different tools
9
9
  for development and for deployment. Tools may include different versions of
10
- ruby, rubygems, bundler etc. Being able to setup an environment appropriately
10
+ ruby, bundler etc. Being able to setup an environment appropriately
11
11
  for each application is becoming increasingly complex and switching from one
12
12
  application to another for development in particular is quickly becoming
13
13
  close to impossible.
@@ -19,9 +19,10 @@ and potentially windows).
19
19
 
20
20
  rconf uses a DSL close to Chef recipes for defining an application configuration.
21
21
  Each application must be equipped with a definition that must reside at the top
22
- level directory of the application and use the '.rconf' file extension. When run
23
- for the first time rconf sets up a .rvmrc file which gets invoked and sets up
24
- the environment each time the application directory gets 'cd-ed' into.
22
+ level directory of the application and use the '.rconf' file extension.
23
+ rconf must be invoked manually using the 'rconf' command line utility to setup
24
+ the environment using the rconf file in the current folder or the one contained
25
+ in a parent folder (the closest parent to the current directory will get used).
25
26
 
26
27
  Internally rconf relies on 'configurators' to configure the machine
27
28
  appropriately. There is one configurator per tool that needs configuration.
@@ -47,53 +48,16 @@ rely on.
47
48
 
48
49
  == INSTALLING
49
50
 
50
- There are two installation cases
51
-
52
- a) you've already got a working install of RVM
53
- b) blank system
54
-
55
- === a) Installing when RVM is already present
56
-
57
51
  It should be as simple as:
58
52
 
59
- gem install rconf
53
+ > gem install rconf
60
54
 
61
55
  and then moving to your repository and running:
62
56
 
63
- rconf
57
+ > rconf
64
58
 
65
59
  to let rconf prepare your environment for the repository.
66
60
 
67
- === b) Installing on a blank system
68
-
69
- If your system fits the requirements listed above, installing rconf will
70
- require you to make a system install of rconf:
71
-
72
- sudo gem install rconf
73
-
74
- then you can go to your repository and run
75
-
76
- rconf
77
-
78
- If you do not have a x.rconf equipped directory and you want rconf to install rvm for
79
- you, you can create a file named dummy.rconf containing:
80
-
81
- ruby do
82
- version 'ruby-1.9.2-p290'
83
- rubygems '1.8.10'
84
- end
85
-
86
- and then run rconf against it:
87
-
88
- rconf dummy.rconf
89
-
90
- === rconf and existing .rvmrc files
91
-
92
- If you have pre-existing .rvmrc files and they don't play well with your
93
- .rconf configuration file, don't hesitate to delete them and run rconf.
94
- rconf will create a new, working, .rvmrc.
95
-
96
-
97
61
  == WRITING RCONF CONFIGURATION FILES
98
62
 
99
63
  rconf uses a ruby DSL for configuration files (.rconf). Each configurator is
data/bin/rconf CHANGED
@@ -44,9 +44,14 @@ where [options] are:
44
44
  opt :verbose,'Print debug output'
45
45
  end
46
46
  if opts[:config].nil? && !opts[:configurators] && !opts[:update] && !opts[:remove]
47
+ search_dir = File.expand_path('..', Dir.pwd)
47
48
  opts[:config] = Dir["./*#{CONFIG_EXTENSION}"]
49
+ while opts[:config].empty? && search_dir != '/'
50
+ opts[:config] = Dir[search_dir + "/*#{CONFIG_EXTENSION}"]
51
+ search_dir = File.expand_path('..', search_dir)
52
+ end
48
53
  if opts[:config].empty?
49
- Trollop::die :config, "not used and could not find a '#{CONFIG_EXTENSION}' file in the working directory"
54
+ Trollop::die :config, "not used and could not find a '#{CONFIG_EXTENSION}' file in the working directory or any parent directory"
50
55
  else
51
56
  opts[:config] = opts[:config].first
52
57
  end
@@ -141,7 +146,7 @@ where [options] are:
141
146
  def update
142
147
  ProgressReporter.report_to_stdout
143
148
  report_check 'Retrieving latest rconf...'
144
- json = Command.execute('curl', '-s', 'http://rubygems.org/api/v1/gems/rconf.json').output
149
+ json = Command.execute('curl', '-s', 'https://rubygems.org/api/v1/gems/rconf.json').output
145
150
  json =~ /"version":"([^"]+)"/
146
151
  version = Regexp.last_match(1)
147
152
  report_fatal 'Failed to retrieve rconf gem information, check network connectivity' unless version
@@ -150,35 +155,19 @@ where [options] are:
150
155
  update_rconf(version)
151
156
  end
152
157
 
153
- # Calls given block with all combination of installed rubies/gemsets
158
+ # Calls given block with all combination of installed rubies
154
159
  #
155
160
  # === Block
156
- # Given block should take two arguments:
161
+ # Given block should take one argument:
157
162
  # ruby(String):: Ruby version
158
- # gemset(String):: Gemset
159
163
  #
160
164
  # === Return
161
165
  # true:: Always return true
162
- def run_in_all_gemsets(&callback)
163
- rubies = Command.execute('rvm', 'list').output
164
- rubies = rubies.split("\n")[3..-1]
165
- report_fatal 'Failed to list install rubies (is rvm in your path?)' unless rubies
166
- rubies.each do |ruby|
167
- if ruby =~ /^(\s+| =>)((ruby|ree|jruby|rbx)[^ ]*)\s.*/
168
- ruby = Regexp.last_match(2)
169
- gemsets = Command.execute('rvm', ruby, 'exec', 'rvm', 'gemset', 'list').output.split("\n")
170
- i = gemsets.index { |gs| gs =~ /^gemsets for #{ruby} / }
171
- if i
172
- gemsets = gemsets[i + 1..-1]
173
- gemsets.each do |gs|
174
- gs = gs.lstrip
175
- callback.call(ruby, gs)
176
- end
177
- else
178
- report_fatal "Failed to retrieve installed gemsets for '#{ruby}'"
179
- end
180
- end
181
- end
166
+ def run_in_all_rubies(&callback)
167
+ rubies = Command.execute('rbenv', 'versions').output
168
+ rubies = rubies.split("\n").map { |r| r[2..-1] } if rubies
169
+ report_fatal 'Failed to list install rubies (is rbenv in your path?)' unless rubies
170
+ rubies.each { |r| callback.call(r) }
182
171
  end
183
172
 
184
173
  # Update rconf for given rubies if required
@@ -189,34 +178,33 @@ where [options] are:
189
178
  # === Return
190
179
  # true:: Always return true
191
180
  def update_rconf(version)
192
- run_in_all_gemsets do |ruby, gs|
193
- report_check("Checking rconf for #{ruby}@#{gs}")
194
- rconf = Command.execute('rvm', "#{ruby}@#{gs}", 'gem', 'list', 'rconf').output
195
- if rconf =~ /rconf \(#{version}/
196
- report_success
197
- elsif rconf =~ /^rconf /
181
+ run_in_all_rubies do |ruby|
182
+ report_check("Checking rconf for #{ruby}")
183
+ rconf = Command.execute('gem', 'list', 'rconf', :env => { 'RBENV_VERSION' => ruby }).output
184
+ if rconf =~ /^rconf / && rconf !~ /rconf \(#{version}/
198
185
  report_failure
199
- report_check("Updating rconf for #{ruby}@#{gs}")
200
- res = Command.execute('rvm', "#{ruby}@#{gs}", 'gem', 'install',
201
- 'rconf', '-v', version, '--no-ri', '--no-rdoc')
186
+ report_check("Updating rconf for #{ruby}")
187
+ res = Command.execute('gem', 'install', 'rconf', '-v', version,
188
+ '--no-ri', '--no-rdoc', :env => { 'RBENV_VERSION' => ruby })
202
189
  report_result(res.success?)
190
+ report(' ' + res.output.red) unless res.success?
203
191
  else
204
- report('SKIPPED (no rconf)')
192
+ report_success
205
193
  end
206
194
  end
207
195
  end
208
196
 
209
- # Remove rconf from all rubies/gemsets
197
+ # Remove rconf from all rubies
210
198
  #
211
199
  # === Return
212
200
  # true:: Always return true
213
201
  def remove
214
202
  ProgressReporter.report_to_stdout
215
- run_in_all_gemsets do |ruby, gs|
216
- rconf = Command.execute('rvm', "#{ruby}@#{gs}", 'gem', 'list', 'rconf').output
203
+ run_in_all_rubies do |ruby|
204
+ rconf = Command.execute('gem', 'list', 'rconf', :env => { 'RBENV_VERSION' => ruby }).output
217
205
  if rconf =~ /^rconf /
218
- report_check("Removing rconf from #{ruby}@#{gs}")
219
- res = Command.execute('rvm', "#{ruby}@#{gs}", 'gem', 'uninstall', '-a', '-x', 'rconf')
206
+ report_check("Removing rconf from #{ruby}")
207
+ res = Command.execute('gem', 'uninstall', '-a', '-x', 'rconf', :env => { 'RBENV_VERSION' => ruby })
220
208
  report_result(res.success?)
221
209
  end
222
210
  end
@@ -231,11 +219,12 @@ where [options] are:
231
219
  # === Return
232
220
  # true:: Always return true
233
221
  def configure(options)
234
- Profile.force_check if options[:force]
235
- Profile.force_reconfigure if options[:reconfigure]
236
222
  ProgressReporter.report_to_stdout
237
223
  ProgressReporter.report_to_file(options[:output]) if options[:output]
224
+ Profile.force_check if options[:force]
225
+ Profile.force_reconfigure if options[:reconfigure]
238
226
  begin
227
+ report("rconf file: #{options[:config].blue}")
239
228
  lang = Language.load(options[:config])
240
229
  report_fatal("Validation of configuration file failed:\n - #{lang.validation_errors.map(&:red).join("\n - ")}") unless lang.validation_errors.empty?
241
230
  report_error(lang.warnings.join(', ').green) unless lang.warnings.empty?
@@ -271,6 +260,5 @@ where [options] are:
271
260
  end
272
261
 
273
262
  # Yeeeehaaaa!
274
- ENV['rvm_interactive_flag'] = '0' # Prevent RVM from re-loading rvmrc
275
263
  trap("INT") { puts "\nAborted!".red; exit 1 }
276
264
  RightConf::Configurer.run
data/lib/rconf/command.rb CHANGED
@@ -32,10 +32,6 @@ module RightConf
32
32
  # === Return
33
33
  # result(CommandResult):: Result of execution (output and exit status)
34
34
  def execute(command, *args)
35
- ENV['rvm_is_not_a_shell_function'] = '0'
36
- ENV['rvm_ignore_rvmrc'] = '1'
37
- ENV['rvm_reload_flag'] = '0'
38
- ENV['rvm_project_rvmrc'] = '0'
39
35
  opts = {}
40
36
  if !args.empty? && args[-1].is_a?(Hash)
41
37
  opts = args[-1]
@@ -66,36 +62,20 @@ module RightConf
66
62
  #
67
63
  # === Return
68
64
  # result(CommandResult):: Result of execution (output and exit status)
69
- # NOTE: This is the result returned by RVM, not the underlying command
70
- # and thus could be successful when the command actually failed...
71
65
  def execute_in_ruby(command, *args)
72
- report_fatal('Failed to run in ruby context, no ruby specified') unless @rvm_prefix
73
- commands = @rvm_prefix + [ 'exec', '--', command ]
74
- args = commands + args
75
- execute('rvm', *args)
76
- end
66
+ report_fatal('Failed to run in ruby context, no ruby specified') unless @ruby_version
67
+ opts = {}; env = {}
68
+ if args[-1].is_a?(Hash)
69
+ opts = args.pop
70
+ env = opts[:env] || {}
71
+ end
72
+ env.merge!({ 'RBENV_VERSION' => @ruby_version })
73
+ opts.merge!({ :env => env })
74
+ args.push(opts)
77
75
 
78
- # Execute rvm command
79
- #
80
- # === Parameters
81
- # command(String):: rvm command to run
82
- # args(Array):: Command arguments
83
- #
84
- # === Options
85
- # abort_on_failure(bool):: Whether to raise an exception in case command
86
- # returns an error (false by default)
87
- # env:: Hash of environment variables keyed by name
88
- #
89
- # === Return
90
- # result(CommandResult):: Result of execution (output and exit status)
91
- def execute_rvm(command, *args)
92
- report_fatal('Failed to run in ruby context, no ruby specified') unless @rvm_prefix
93
- commands = @rvm_prefix + [ command ]
94
- args = commands + args
95
- execute('rvm', *args)
76
+ execute(command, *args)
96
77
  end
97
78
 
98
-
99
79
  # Execute given command with given arguments using 'sudo'
100
80
  #
101
81
  # === Parameters
@@ -144,13 +124,12 @@ module RightConf
144
124
  # Set ruby to be used by 'execute_in_ruby'
145
125
  #
146
126
  # === Parameters
147
- # ruby(String):: RVM ruby
148
- # gemset(String):: RVM gemset
127
+ # version(String):: rbenv ruby version
149
128
  #
150
129
  # === Return
151
130
  # true:: Always return true
152
- def set_ruby(ruby, gemset)
153
- @rvm_prefix = ["#{ruby}@#{gemset}"]
131
+ def set_ruby(version)
132
+ @ruby_version = version
154
133
  true
155
134
  end
156
135
 
@@ -88,7 +88,7 @@ module RightConf
88
88
  # nil:: If settings are valid for this configurator
89
89
  # error(String):: Error message otherwise
90
90
  def validate
91
- @settings_values.merge!(OverridesLanguage.overrides_for(self.class.key.to_s)) unless Profile.force_reconfigure?
91
+ @settings_values.merge!(OverridesLanguage.overrides_for(self.class.key.to_s))
92
92
  if e = OverridesLanguage.parse_error
93
93
  error = "Could not load overrides file '#{OverridesLanguage::OVERRIDES_FILE}' (#{e.message})"
94
94
  else
@@ -147,8 +147,8 @@ module RightConf
147
147
  report_check('Installing passenger+nginx')
148
148
  # Grrrrr passenger installer expect rake where it's not... HACK
149
149
  ruby_dir = File.dirname(`which ruby`.chomp)
150
- if ruby_dir !~ /\.rvm/
151
- post_note 'Please enable rvm before passenger is installed by running ' + 'cd ..;cd -'.blue
150
+ if ruby_dir !~ /\.rbenv/
151
+ post_note 'Please init rbenv before passenger is installed by running ' + 'cd ..;cd -'.blue
152
152
  report_failure
153
153
  else
154
154
  FileUtils.cp(`which rake`.chomp, ruby_dir) unless rake_exist = File.exist?(File.join(ruby_dir, 'rake'))
@@ -257,21 +257,21 @@ http {
257
257
  #####################################################################
258
258
  set $is_library_direct "";
259
259
 
260
- # request is for a library related action
260
+ # request is for a library related action
261
261
  if ($request_uri ~ ^/library/)
262
262
  {
263
263
  set $is_library_direct L;
264
264
  }
265
-
265
+
266
266
  # request is a POST
267
267
  if ($request_method = POST)
268
268
  {
269
- set $is_library_direct "${is_library_direct}P";
269
+ set $is_library_direct "${is_library_direct}P";
270
270
  }
271
-
271
+
272
272
  # request is an AJAX
273
273
  if ($http_x_requested_with = XMLHttpRequest)
274
- {
274
+ {
275
275
  set $is_library_direct "${is_library_direct}A";
276
276
  }
277
277
 
@@ -313,8 +313,8 @@ http {
313
313
  proxy_set_header X-Core-Site-Domain 'right-site.rightscale.local';
314
314
  }
315
315
 
316
- # library static assets get proxied directly to the library app
317
- location ~ ^/library/(.*)\.(css|js)$ {
316
+ # library static assets get proxied directly to the library app
317
+ location ~ ^/library/(.*)\.(css|js|html)$ {
318
318
  proxy_pass http://library.rightscale.local:3001/$1.$2;
319
319
  }
320
320
 
@@ -334,21 +334,21 @@ http {
334
334
  #####################################################################
335
335
  set $is_global_system_direct "";
336
336
 
337
- # request is for a library related action
337
+ # request is for a library related action
338
338
  if ($request_uri ~ ^/global/)
339
339
  {
340
340
  set $is_global_system_direct L;
341
341
  }
342
-
342
+
343
343
  # request is a POST
344
344
  if ($request_method = POST)
345
345
  {
346
- set $is_global_system_direct "${is_global_system_direct}P";
346
+ set $is_global_system_direct "${is_global_system_direct}P";
347
347
  }
348
-
348
+
349
349
  # request is an AJAX
350
350
  if ($http_x_requested_with = XMLHttpRequest)
351
- {
351
+ {
352
352
  set $is_global_system_direct "${is_global_system_direct}A";
353
353
  }
354
354
 
@@ -18,17 +18,9 @@ module RightConf
18
18
  register :ruby
19
19
 
20
20
  description "Installs ruby interpreter and rubygems.\n" +
21
- 'Installs and uses rvm on supported (i.e. non-Windows) platforms'
21
+ 'Installs and uses rbenv on supported (i.e. non-Windows) platforms'
22
22
 
23
- setting 'version', 'Ruby version using rvm notation (see "rvm list known")', :required => true
24
- setting 'rubygems', 'Rubygems version, e.g. "1.3.7"'
25
- setting 'gemset', 'Gemset to be used for platforms supporting rvm'
26
-
27
- # RVM version used to install rubies
28
- RVM_VERSION = '1.10.2'
29
-
30
- # RVM releases URL
31
- RVM_RELEASES_URL = 'https://rvm.io/releases'
23
+ setting 'version', 'Ruby version using rbenv notation (see "rbenv versions")', :required => true
32
24
 
33
25
  # Let configurator run, it is idempotent
34
26
  #
@@ -41,78 +33,23 @@ module RightConf
41
33
  alias :check_windows :check_linux
42
34
 
43
35
  # Switch to ruby version defined in settings
44
- # Use rvm and install it if needed
36
+ # Use rbenv and install it if needed
45
37
  #
46
38
  # === Return
47
39
  # true:: Always return true
48
40
  def run_linux
49
- check_rvm(RVM_VERSION)
50
- return true if aborting
51
- Command.set_ruby(version, gemset)
52
- report_check("Checking whether #{version} is the active ruby")
53
- out = Command.execute('rvm', 'current').output
54
- if out =~ /^#{version.gsub('.', '\\.')}/
55
- report_success
56
- check_rvmrc
57
- else
58
- report_failure
59
- report_check("Switching to #{version}")
60
- out = Command.execute('rvm', 'use', version).output
61
- case out
62
- when /is not installed\./
63
- report_failure
64
- report_fatal "Failed to install #{ruby}" if @tried
65
- Platform.dispatch(version) { :install_ruby }
66
- @tried = true
67
- Command.execute_in_ruby('gem', 'install', 'rconf') unless gemset
68
- run
69
- return true
70
- when /^Using /
71
- report_success
72
- check_rvmrc
73
- else
74
- report_fatal("Failed to use #{version}:\n#{out}")
75
- end
76
- end
77
- if gemset
78
- report_check("Checking whether gemset #{gemset} exists")
79
- res = Command.execute('rvm', version, 'exec', 'rvm', 'gemset', 'list')
80
- if res.output =~ /^(\s+|=> )#{gemset}$/
81
- report_success
82
- else
83
- report_failure
84
- report_check("Creating gemset #{gemset} for #{version}")
85
- Command.execute('rvm', version, 'exec', 'rvm', 'gemset', 'create', gemset,
86
- :abort_on_failure => "Failed to create gemset '#{gemset}'")
87
- end
88
- report_check("Switching to gemset #{gemset}")
89
- Command.execute('rvm', version, 'exec', 'rvm', 'gemset', 'use', gemset,
90
- :abort_on_failure => "Failed to switch to gemset '#{gemset}'")
91
- report_success
92
- report_check("Checking whether rconf is installed")
93
- res = Command.execute_in_ruby('rconf', '--version')
94
- if res.output =~ /#{RightConf::VERSION}/
95
- report_success
96
- else
97
- report_failure
98
- report_check("Installing rconf")
99
- Command.execute_in_ruby('gem', 'install', 'rconf', :abort_on_failure => "Failed to install rconf")
100
- report_success
101
- end
102
- end
103
- if rubygems
104
- report_check("Checking whether rubygems #{rubygems} is installed")
105
- res = Command.execute_in_ruby('gem', '--version')
106
- if res.success? && res.output =~ /^#{rubygems}$/
107
- report_success
108
- else
109
- report_failure
110
- report_check("Installing rubygems #{rubygems}")
111
- Command.execute_rvm('rubygems', rubygems, :abort_on_failure => 'Failed to install rubygems')
112
- report_success
113
- end
41
+ if Command.execute('rvm').success?
42
+ report_fatal "rconf detected an installation of RVM, rconf now uses rbenv to configure ruby versions.\n" +
43
+ "Unfortunately rbenv and RVM cannot be installed together on the same machine (see https://github.com/sstephenson/rbenv/).\n" +
44
+ "Please uninstall RVM and try again ('rvm implode' will delete RVM and all installed rubies and gems).\n" +
45
+ "Once RVM is uninstalled please start a new shell (you may also need to remove references to RVM from your ~/.bash_profile)"
46
+ return true
114
47
  end
115
- true
48
+ check_rbenv
49
+ return true if aborting
50
+ check_ruby
51
+ Command.set_ruby(ruby_version)
52
+ true
116
53
  end
117
54
  alias :run_darwin :run_linux
118
55
 
@@ -124,93 +61,103 @@ module RightConf
124
61
  def run_windows
125
62
  end
126
63
 
127
- # Set command prefix when already configured
128
- # Re-create .rvmrc if needed
64
+ protected
65
+
66
+ # Make version compatible with RVM
67
+ def ruby_version
68
+ @ruby_version ||= version.start_with?('ruby-') ? version[5..-1] : version
69
+ end
70
+
71
+ # Check whether rbenv and ruby-build are installed and installs it/them if not
129
72
  #
130
73
  # === Return
131
74
  # true:: Always return true
132
- def post_process
133
- Command.set_ruby(version, gemset)
134
- check_rvmrc
135
- true
75
+ def check_rbenv
76
+ res = Command.execute('rbenv')
77
+ rbenv_in_path = res.success?
78
+ if rbenv_in_path
79
+ res.output =~ /^rbenv ([0-9]+)\.([0-9]+)\.([0-9]+)$/
80
+ maj, min, build = [$1.to_i, $2.to_i, $3.to_i]
81
+ if maj == 0 && min < 4
82
+ report_fatal("rconf requires rbenv version 0.4.0 or greater, you have #{maj}.#{min}.#{build} installed, please upgrade (e.g. via brew upgrade rbenv) and try again")
83
+ end
84
+ return true
85
+ end
86
+ rbenv_present = File.exist?(File.join(ENV['HOME'], '.rbenv', 'bin', 'rbenv'))
87
+ update_msg = "You should add 'eval \"$(rbenv init -)\"' to your .bash_profile / .bashrc etc. " +
88
+ "so rbenv is properly initialized in new shells, the following assumes ~/.bash_profile is used (Mac OS X):\n\n" +
89
+ "echo 'eval \"$(rbenv init -)\"' >> ~/.bash_profile\n\n".blue +
90
+ "You should also update your PATH environment variable with:\n\n" +
91
+ "echo 'export PATH=\"$HOME/.rbenv/shims:$PATH\" >> ~/.bash_profile'\n".blue
92
+ if rbenv_present
93
+ post_note "rconf detected rbenv is installed in #{rbenv_path} but it is not in the PATH.\n" + update_msg
94
+ aborting(true)
95
+ return true
96
+ else
97
+ opts = { :report => true, :post_install => update_msg }.merge(abort_option('Failed to install rbenv'))
98
+ PackageInstaller.install('rbenv', opts)
99
+ opts = { :report => true }.merge(abort_option('Failed to install ruby-build'))
100
+ PackageInstaller.install('ruby-build', opts) { !Command.execute('ruby-build') }
101
+ true
102
+ end
136
103
  end
137
104
 
138
- protected
139
-
140
- # Check whether the right version of RVM is installed and install it if not
141
- #
142
- # === Parameters
143
- # version(String):: Version of RVM to be checked, e.g. '1.2.6'
105
+ # Check .ruby-version and its content
144
106
  #
145
107
  # === Return
146
108
  # true:: Always return true
147
- def check_rvm(version)
148
- report_check("Checking that rvm #{version} is installed")
149
- out = Command.execute('rvm', '--version').output
150
- if out =~ /rvm #{RVM_VERSION.gsub('.', '\\.')}/
151
- report_success
152
- else
153
- report_failure
154
- if out =~ /rvm ([^\s]+)/
155
- report_error "WARNING!: You have rvm #{Regexp.last_match[1]} installed which may not be compatible with rconf.\n" +
156
- "rconf will proceed and try to install rvm #{version}."
157
- end
158
- report_check("Installing rvm #{version}")
159
- rvm_src = File.join(ENV['HOME'] || '/root', '.rvm/src')
160
- FileUtils.mkdir_p(rvm_src)
161
- Dir.chdir(rvm_src) do
162
- Command.execute('curl', '-O', '-f',
163
- "#{RVM_RELEASES_URL}/rvm-#{version}.tar.gz",
164
- :abort_on_failure => "Failed to download rvm #{version}")
165
- Command.execute('tar', 'zxf', "rvm-#{version}.tar.gz",
166
- :abort_on_failure => "Failed to extract rvm tgz from #{File.join(Dir.getwd, 'rvm-' + version + '.tar.gz')}")
167
- end
168
- Dir.chdir(File.join(rvm_src, "rvm-#{version}")) do
169
- Command.execute('./install', :abort_on_failure => "Failed to install rvm #{version}")
109
+ def check_ruby
110
+ exists = File.exist?('.ruby-version')
111
+ if exists
112
+ contents = IO.read('.ruby-version')
113
+ right_ruby = !!(contents =~ /#{ruby_version}/)
114
+ end
115
+
116
+ unless exists && right_ruby
117
+ unless Command.execute('rbenv', 'local', ruby_version).success?
118
+ report_check("Installing ruby #{ruby} (this will take a while, please be patient)")
119
+ Platform.dispatch(ruby_version) { :install_ruby }
120
+ Command.execute('rbenv', 'local', ruby_version)
170
121
  end
171
- post_note "Configuration required installing RVM, please start a new shell to activate it and re-run rconf to finish configuration".green
172
- aborting(true)
173
- report_success
174
122
  end
175
- setup_bashrc
176
123
  true
177
124
  end
178
125
 
179
- # Install given ruby version using rvm
126
+ # Install given ruby version using rbenv
127
+ # Install any prerequesites first
180
128
  #
181
129
  # === Parameters
182
- # ruby(String):: Ruby version compatible with rvm
130
+ # ruby(String):: Ruby version compatible with rbenv
183
131
  #
184
132
  # === Return
185
133
  # true:: Always return true
186
134
  def install_ruby(ruby)
187
135
  Platform.dispatch(ruby) { :install_ruby_prerequisites }
188
- report_check("Installing #{ruby} (this will take a while, please be patient)")
189
- Command.execute('rvm', 'install', ruby, :abort_on_failure => 'Failed to install ruby')
136
+ # Can't abort on failure rbenv install seems to exist with a non zero error code even when successful :(
137
+ Command.execute('rbenv', 'install', ruby)
190
138
  report_success
191
139
  true
192
140
  end
193
141
 
194
- # Install given ruby version using rvm
195
- # On Lion, need to setup CC env var before running rvm install
142
+ # Install given ruby version using rbenv
143
+ # On Lion, need to setup CC env var before running rbenv install
196
144
  #
197
145
  # === Parameters
198
- # ruby(String):: Ruby version compatible with rvm
146
+ # ruby(String):: Ruby version compatible with rbenv
199
147
  #
200
148
  # === Return
201
149
  # true:: Always return true
202
150
  def install_ruby_darwin(ruby)
203
- report_check("Installing #{ruby} (this will take a while, please be patient)")
204
- version = `system_profiler SPDeveloperToolsDataType -xml | xpath "//*[text()='_items']/following-sibling::array/dict/child::key[text()='spdevtools_version']/following-sibling::string/text()" 2> /dev/null`
151
+ c_version = `system_profiler SPDeveloperToolsDataType -xml | xpath "//*[text()='_items']/following-sibling::array/dict/child::key[text()='spdevtools_version']/following-sibling::string/text()" 2> /dev/null`
205
152
  env = {}
206
- if version =~ /^4\.2\.[0-9]+/
153
+ if c_version =~ /^4\.2\.[0-9]+/
207
154
  if !File.executable?('/usr/bin/gcc-4.2')
208
- report_fatal("The C compiler included with Xcode #{version} produces buggy ruby interpreters, please install the C compilers from https://github.com/downloads/kennethreitz/osx-gcc-installer/GCC-10.7-v2.pkg and re-run rconf")
155
+ report_fatal("The C compiler included with Xcode #{c_version} produces buggy ruby interpreters, please install the C compilers from https://github.com/downloads/kennethreitz/osx-gcc-installer/GCC-10.7-v2.pkg or update your version of Xcode and re-run rconf")
209
156
  else
210
157
  env['CC'] = '/usr/bin/gcc-4.2'
211
158
  end
212
159
  end
213
- Command.execute('rvm', 'install', ruby, :abort_on_failure => 'Failed to install ruby', :env => env)
160
+ Command.execute('rbenv', 'install', ruby, :abort_on_failure => 'Failed to install ruby', :env => env)
214
161
  report_success
215
162
  end
216
163
 
@@ -254,80 +201,17 @@ module RightConf
254
201
  true
255
202
  end
256
203
 
257
- # Check .rvmrc and its content
258
- #
259
- # === Return
260
- # true:: Always return true
261
- def check_rvmrc
262
- if !File.exist?('.rvmrc') || IO.read('.rvmrc') !~ /#{version}@#{gemset}/
263
- report_check('Setting up .rvmrc')
264
- begin
265
- File.open('.rvmrc', 'w') do |f|
266
- f.puts "environment_id=\"#{version}@#{gemset}\""
267
- f.puts RVM_HOOK
268
- f.puts "type -P rconf &>/dev/null && { rconf; }"
269
- f.puts "type -P rconf &>/dev/null || { echo 'rconf not installed, skipping (see .rvmrc)'; }"
270
- end
271
- report_success
272
- post_note "Configuration required switching the active ruby\nPlease run " + 'cd ..;cd -'.blue + ' to activate it and finish configuration'.green
273
- aborting(true)
274
- rescue Exception => e
275
- report_failure
276
- report_error(e.message)
277
- end
278
- end
279
- true
280
- end
281
-
282
- # rvm mojo for creating and enabling 'environments'
283
- RVM_HOOK = <<-EOF
284
- if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
285
- && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
286
- then
287
- \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
288
-
289
- if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
290
- then
291
- . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
292
- fi
293
- else
294
- # If the environment file has not yet been created, use the RVM CLI to select.
295
- if ! rvm --create "$environment_id"
296
- then
297
- echo "Failed to create RVM environment '${environment_id}'."
298
- return 1
299
- fi
300
- fi
301
- if [[ $- == *i* ]] # check for interactive shells
302
- then
303
- echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
304
- else
305
- echo "Using: $GEM_HOME" # don't use colors in interactive shells
306
- fi
307
- EOF
308
204
 
309
- # Setup .bashrc for rvm support
205
+ # Produce abort on failure option
310
206
  #
311
- # === Return
312
- # true:: Always return true
313
- def setup_bashrc
314
- if EnvironmentUpdater.update(rvm_bash_activation, ['PATH'])
315
- post_note '.rvmrc was updated, please reload your shell to activate it and re-run rconf'
316
- aborting(true)
317
- end
318
- end
319
-
320
- # rvm bash activation code
207
+ # === Parameters
208
+ # message(String):: Abort message to be used in case abort option should be set
321
209
  #
322
210
  # === Return
323
- # code(String):: Code that needs to be added to bashrc to activate rvm
324
- def rvm_bash_activation
325
- code = <<EOS
326
- export rvm_trust_rvmrcs_flag=1
327
- if [[ -n "$PS1" ]]; then
328
- if [[ -s $HOME/.rvm/scripts/rvm ]] ; then source $HOME/.rvm/scripts/rvm ; fi
329
- fi
330
- EOS
211
+ # {}:: Empty hash if 'abort_on_failure' is notset
212
+ # opts(Hash):: Abort option with give message otherwise
213
+ def abort_option(message)
214
+ opts = abort_on_failure && { :abort_on_failure => message } || {}
331
215
  end
332
216
 
333
217
  end
@@ -17,14 +17,18 @@ module RightConf
17
17
  # Path to overrides file
18
18
  OVERRIDES_FILE = File.join(ENV['HOME'], '.rconf_overrides')
19
19
 
20
+ # Lexical token used to indicate that the value of an overridden configurator attribute should literally
21
+ # be nil, not the string "nil" or "none".
22
+ NIL_LITERAL = /^(nil|none)$/
23
+
24
+
20
25
  # Return override for given configurator setting if any
21
26
  #
22
27
  # === Parameters
23
28
  # key(String):: Configurator key
24
- # setting(String):: Setting name
25
29
  #
26
30
  # === Return
27
- # value(String||Nil):: Override value if any, nil otherwise
31
+ # value(String||Nil):: Override values if any, nil otherwise
28
32
  def self.overrides_for(key)
29
33
  self.load unless @overrides
30
34
  @overrides && @overrides[key] || {}
@@ -85,11 +89,18 @@ module RightConf
85
89
  if operands.size != 2
86
90
  raise "Invalid syntax '#{o}', must be of the form 'key.setting=value'"
87
91
  end
92
+
88
93
  if operands[1].start_with?('"') || operands[1].start_with?("'")
94
+ # Quoted string
89
95
  value = operands[1]
96
+ elsif operands[1] =~ NIL_LITERAL
97
+ # Literal nil
98
+ value = 'nil'
90
99
  else
100
+ # Anything else: assume unquoted string
91
101
  value = "'#{operands[1]}'"
92
102
  end
103
+
93
104
  overrides.instance_eval("@#{operands[0]}=#{value}")
94
105
  end
95
106
  rescue Exception => e
@@ -142,4 +153,3 @@ module RightConf
142
153
 
143
154
  end
144
155
  end
145
-
@@ -23,6 +23,7 @@ module RightConf
23
23
  # opts[:abort_on_failure](String):: Optional, abort configuration
24
24
  # and display given error message if install fails when set
25
25
  # opts[:report](TrueClass|FalseClass):: Whether to report installation
26
+ # opts[:post_install](String):: Message displayed only when software was installed
26
27
  #
27
28
  # === Block
28
29
  # If a block is given it will get called with no argument prior to the
@@ -47,6 +48,7 @@ module RightConf
47
48
  report_check("Installing #{packages.join(', ')}") if report
48
49
  Platform.dispatch(packages, opts) { :install }
49
50
  report_success if report
51
+ opts && opts[:post_install] && report('Note: '.blue + opts[:post_install])
50
52
  end
51
53
  true
52
54
  end
data/lib/rconf/version.rb CHANGED
@@ -11,9 +11,9 @@
11
11
 
12
12
  module RightConf
13
13
 
14
- MAJOR = 0
15
- MINOR = 10
16
- BUILD = 1
14
+ MAJOR = 1
15
+ MINOR = 0
16
+ BUILD = 0
17
17
 
18
18
  VERSION = [MAJOR, MINOR, BUILD].map(&:to_s).join('.')
19
19
 
@@ -28,11 +28,11 @@ describe RightConf::BundlerConfigurator do
28
28
 
29
29
  before(:each) do
30
30
  @configurator = create_configurator('bundler { version "0" }')
31
- RightConf::Command.instance.instance_variable_set(:@rvm_prefix, 'r@g')
31
+ RightConf::Command.instance.instance_variable_set(:@ruby_prefix, '0')
32
32
  end
33
33
 
34
34
  after(:each) do
35
- RightConf::Command.instance.instance_variable_set(:@rvm_prefix, nil)
35
+ RightConf::Command.instance.instance_variable_set(:@ruby_prefix, nil)
36
36
  end
37
37
 
38
38
  it 'should succeed when bundler succeeds' do
@@ -13,95 +13,65 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
13
13
 
14
14
  describe RightConf::RubyConfigurator do
15
15
 
16
- RVM_VERSION = RightConf::RubyConfigurator::RVM_VERSION
17
-
18
16
  def success_result(output=nil)
19
17
  flexmock('res', :success? => true, :output => output)
20
18
  end
21
19
 
22
- before(:each) do
23
- @configurator = create_configurator('ruby { version "0"; rubygems "1" }')
24
- flexmock(File).should_receive(:exist?).with('.rvmrc').and_return(true)
25
- flexmock(IO).should_receive(:read).with('.rvmrc').and_return("anything")
26
- flexmock(File).should_receive(:open).with('.rvmrc', 'w').and_yield(FlexMock.undefined) # Don't override rconf's .rvmrc...
20
+ def failure_result(output=nil)
21
+ flexmock('res', :success? => false, :output => output)
27
22
  end
28
23
 
29
- it 'should succeed on linux when rvm succeeds' do
30
- should_execute('rvm', '--version').once.and_return(success_result("rvm #{RVM_VERSION}"))
31
- should_execute('rvm', 'current').once.and_return(success_result("0@"))
32
- should_execute('rvm', '0@', 'exec', '--', 'gem', '--version').once.and_return(success_result('1'))
33
- @configurator.run_linux
24
+ before(:each) do
25
+ @configurator = create_configurator('ruby { version "42" }')
34
26
  end
35
27
 
36
- it 'should install rvm if needed' do
37
- rvm_tar = "rvm-#{RVM_VERSION}.tar.gz"
38
- should_execute('rvm', '--version').once.and_return(success_result("rvm"))
39
- should_execute('curl', '-O', '-f', "https://rvm.io/releases/#{rvm_tar}",
40
- {:abort_on_failure=>"Failed to download rvm #{RVM_VERSION}"}).once.and_return(success_result)
41
- should_execute('tar', 'zxf', rvm_tar,
42
- {:abort_on_failure=>"Failed to extract rvm tgz from #{File.expand_path(File.join(File.dirname(__FILE__), '..', '..', "rvm-#{RVM_VERSION}.tar.gz"))}"}).once.and_return(success_result)
43
- flexmock(Dir).should_receive(:chdir).and_yield
44
- should_execute('./install', {:abort_on_failure=>"Failed to install rvm #{RVM_VERSION}"}).once.and_return(success_result)
45
- should_execute('rvm', 'use', '0').never
46
- @configurator.run_linux
28
+ it 'should abort if rvm is present' do
29
+ should_execute('rvm').once.and_return(success_result)
30
+ expect { @configurator.run_linux }.to raise_error
47
31
  end
48
32
 
49
- it 'should install rubygems if needed' do
50
- should_execute('rvm', '--version').once.and_return(success_result("rvm #{RVM_VERSION}"))
51
- should_execute('rvm', 'current').once.and_return(success_result("0@"))
52
- should_execute('rvm', '0@', 'exec', '--', 'gem', '--version').once.and_return(success_result('0'))
53
- should_execute('rvm', '0@', 'rubygems', '1',
54
- {:abort_on_failure=>'Failed to install rubygems'}).once.and_return(success_result)
55
- @configurator.run_linux
56
- end
57
- end
33
+ context "with rbenv installed" do
34
+ before(:each) do
35
+ should_execute('rvm').once.and_return(failure_result)
36
+ flexmock(File).should_receive(:exist?).with('.ruby-version').and_return(true)
37
+ flexmock(IO).should_receive(:read).with('.ruby-version').and_return("42")
38
+ end
58
39
 
59
- describe 'bashrc update' do
40
+ it 'should succeed' do
41
+ should_execute('rbenv').once.and_return(success_result('rbenv 0.4.0'))
42
+ @configurator.run_linux
43
+ end
60
44
 
61
- before(:each) do
62
- flexmock(File).should_receive(:exist?).with(File.join(ENV['HOME'], '.bash_profile')).once.and_return(true)
63
- flexmock(File).should_receive(:exist?).with('.rvmrc').and_return(true)
64
- flexmock(FileUtils).should_receive(:mv).and_return(true)
65
- f = flexmock('f')
66
- f.should_receive(:puts).and_return { |c| @bashrc_content = c }
67
- flexmock(File).should_receive(:open).and_yield(f)
68
- @configurator = create_configurator('ruby { version "0"; rubygems "1" }', :enable_updater => true)
69
- @rvm_bash_activation = @configurator.__send__(:rvm_bash_activation)
70
- end
45
+ it 'should check rbenv version' do
46
+ should_execute('rbenv').once.and_return(success_result('rbenv 0.3.0'))
47
+ expect { @configurator.run_linux }.to raise_error
48
+ end
71
49
 
72
- it 'should install rvm hook in bashrc when not present' do
73
- flexmock(IO).should_receive(:read).and_return('test')
74
- @configurator.__send__(:setup_bashrc)
75
- @bashrc_content.should == "#{@rvm_bash_activation}\ntest"
76
50
  end
77
51
 
78
- it 'should not install rvm hook in bashrc when present' do
79
- flexmock(IO).should_receive(:read).and_return('test' + @rvm_bash_activation)
80
- @configurator.__send__(:setup_bashrc)
81
- @bashrc_content.should be_nil
82
- end
52
+ context "without rbenv installed" do
53
+ before(:each) do
54
+ should_execute('rvm').once.and_return(failure_result)
55
+ should_execute('rbenv').once.and_return(failure_result)
56
+ flexmock(File).should_receive(:exist?).with('.ruby-version').and_return(false)
57
+ flexmock(File).should_receive(:exist?).with(File.join(ENV['HOME'], '.rbenv', 'bin', 'rbenv')).and_return(false)
58
+ end
83
59
 
84
- it 'should install rvm hook after path is set' do
85
- flexmock(IO).should_receive(:read).and_return(<<-EOS
86
- echo 'zobi la mouche'
87
- radio killed the radio star
88
- #PATH=something:should be fine
89
- this should not:
90
- PATH=something
91
- AFTER
92
- EOS
93
- )
94
- @configurator.__send__(:setup_bashrc)
95
- @bashrc_content.should == <<-EOS
96
- echo 'zobi la mouche'
97
- radio killed the radio star
98
- #PATH=something:should be fine
99
- this should not:
100
- PATH=something
101
- #{@rvm_bash_activation}
102
- AFTER
103
- EOS
60
+ it 'should install rbenv and ruby-build' do
61
+ flexmock(RightConf::PackageInstaller).should_receive(:install).with('rbenv', Hash).once
62
+ flexmock(RightConf::PackageInstaller).should_receive(:install).with('ruby-build', Hash, Proc).once
63
+ should_execute('rbenv', 'local', '42').and_return(success_result)
64
+ @configurator.run_linux
65
+ end
66
+
67
+ it 'should install ruby if needed' do
68
+ flexmock(RightConf::PackageInstaller).should_receive(:install).with('rbenv', Hash).once
69
+ flexmock(RightConf::PackageInstaller).should_receive(:install).with('ruby-build', Hash, Proc).once
70
+ should_execute('rbenv', 'local', '42').and_return(failure_result)
71
+ flexmock(RightConf::Platform).should_receive(:dispatch).with('42', Proc)
72
+ should_execute('rbenv', 'local', '42').and_return(success_result)
73
+ @configurator.run_linux
74
+ end
104
75
  end
105
76
 
106
77
  end
107
-
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rconf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-27 00:00:00.000000000 Z
12
+ date: 2013-03-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -66,6 +66,7 @@ extensions: []
66
66
  extra_rdoc_files: []
67
67
  files:
68
68
  - .gitignore
69
+ - CHANGES
69
70
  - Gemfile
70
71
  - LICENSE
71
72
  - README.rdoc
@@ -142,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
143
  version: '0'
143
144
  requirements: []
144
145
  rubyforge_project: rconf
145
- rubygems_version: 1.8.24
146
+ rubygems_version: 1.8.23
146
147
  signing_key:
147
148
  specification_version: 3
148
149
  summary: Cross platform environment configuration