autoproj 2.0.0.rc4 → 2.0.0.rc5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/bin/alocate +1 -1
- data/bin/autoproj +5 -4
- data/bin/autoproj_bootstrap +205 -26
- data/bin/autoproj_bootstrap.in +7 -1
- data/bin/autoproj_install +198 -25
- data/lib/autoproj.rb +1 -0
- data/lib/autoproj/cli.rb +1 -2
- data/lib/autoproj/cli/commit.rb +1 -2
- data/lib/autoproj/cli/locate.rb +4 -3
- data/lib/autoproj/cli/log.rb +0 -1
- data/lib/autoproj/cli/main.rb +24 -6
- data/lib/autoproj/cli/reset.rb +1 -0
- data/lib/autoproj/cli/status.rb +3 -2
- data/lib/autoproj/cli/tag.rb +8 -3
- data/lib/autoproj/cli/upgrade.rb +43 -39
- data/lib/autoproj/environment.rb +8 -0
- data/lib/autoproj/exceptions.rb +4 -0
- data/lib/autoproj/find_workspace.rb +83 -0
- data/lib/autoproj/ops/install.rb +198 -25
- data/lib/autoproj/os_package_installer.rb +5 -1
- data/lib/autoproj/os_package_resolver.rb +15 -5
- data/lib/autoproj/package_managers/bundler_manager.rb +98 -46
- data/lib/autoproj/package_set.rb +4 -7
- data/lib/autoproj/reporter.rb +4 -0
- data/lib/autoproj/system.rb +2 -2
- data/lib/autoproj/version.rb +1 -1
- data/lib/autoproj/workspace.rb +7 -63
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df06bafc27ce59e3c5ad6c46590c44045755f496
|
4
|
+
data.tar.gz: 340b8871ba997370ed1b8b6fc526a7388c30de18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44b11ccb7dacb6e6dac7f3fad212c5755e5fd00fb2416ef303744333b7c26afa09894af22a755a3ef69dbdc04a4d05f87a556e104ebb87e7fc35c8e67cac1e3b
|
7
|
+
data.tar.gz: e65540e5a2a77faf9e10e0a425e5f723ae25737f76575ed0e31b2050e66e6072c2210c0431f90da82e9fa237ef642b5e153c45ff3e62afe032a00afb0960c71f
|
data/.travis.yml
CHANGED
data/bin/alocate
CHANGED
data/bin/autoproj
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'autoproj'
|
4
|
-
require 'autoproj/autobuild'
|
5
3
|
require 'autoproj/cli'
|
6
4
|
require 'autoproj/cli/main'
|
7
5
|
Autoproj::CLI.basic_setup
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
argv = ARGV.find_all { |arg| arg != "--no-plugins" }
|
8
|
+
if argv.size == ARGV.size
|
9
|
+
Autoproj::CLI.load_plugins
|
10
|
+
end
|
11
|
+
Autoproj::CLI::Main.start(argv)
|
11
12
|
|
data/bin/autoproj_bootstrap
CHANGED
@@ -5,6 +5,7 @@ if RUBY_VERSION < "1.9.2"
|
|
5
5
|
exit 1
|
6
6
|
end
|
7
7
|
|
8
|
+
require 'pathname'
|
8
9
|
require 'optparse'
|
9
10
|
require 'fileutils'
|
10
11
|
require 'yaml'
|
@@ -17,19 +18,65 @@ module Autoproj
|
|
17
18
|
# It can be required standalone (i.e. does not depend on anything else than
|
18
19
|
# ruby and the ruby standard library)
|
19
20
|
class Install
|
21
|
+
class UnexpectedBinstub < RuntimeError; end
|
22
|
+
|
20
23
|
# The directory in which to install autoproj
|
21
24
|
attr_reader :root_dir
|
22
25
|
# Content of the Gemfile generated to install autoproj itself
|
23
26
|
attr_accessor :gemfile
|
27
|
+
# The environment that is passed to the bundler installs
|
28
|
+
attr_reader :env
|
24
29
|
|
25
30
|
def initialize(root_dir)
|
26
31
|
@root_dir = root_dir
|
27
|
-
|
32
|
+
if File.file?(autoproj_gemfile_path)
|
33
|
+
@gemfile = File.read(autoproj_gemfile_path)
|
34
|
+
else
|
35
|
+
@gemfile = default_gemfile_contents
|
36
|
+
end
|
37
|
+
|
28
38
|
@private_bundler = false
|
29
39
|
@private_autoproj = false
|
30
40
|
@private_gems = false
|
41
|
+
@local = false
|
42
|
+
@env = self.class.clean_env
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.clean_env
|
46
|
+
env = Hash.new
|
47
|
+
env['RUBYLIB'] = []
|
48
|
+
env['GEM_PATH'] = []
|
49
|
+
%w{PATH GEM_HOME}.each do |name|
|
50
|
+
env[name] = sanitize_env(ENV[name] || "")
|
51
|
+
end
|
52
|
+
env['BUNDLE_GEMFILE'] = nil
|
53
|
+
env
|
54
|
+
end
|
55
|
+
|
56
|
+
def env_for_child
|
57
|
+
env.inject(Hash.new) do |h, (k, v)|
|
58
|
+
h[k] = (v.join(File::PATH_SEPARATOR) if v && !v.empty?)
|
59
|
+
h
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.sanitize_env(value)
|
64
|
+
value.split(File::PATH_SEPARATOR).
|
65
|
+
find_all { |p| !in_workspace?(p) }
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.in_workspace?(base_dir)
|
69
|
+
path = Pathname.new(base_dir)
|
70
|
+
while !path.root?
|
71
|
+
if (path + ".autoproj").exist? || (path + "autoproj").exist?
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
path = path.parent
|
75
|
+
end
|
76
|
+
return false
|
31
77
|
end
|
32
78
|
|
79
|
+
|
33
80
|
def dot_autoproj; File.join(root_dir, '.autoproj') end
|
34
81
|
def bin_dir; File.join(dot_autoproj, 'bin') end
|
35
82
|
def bundler_install_dir; File.join(dot_autoproj, 'bundler') end
|
@@ -38,13 +85,24 @@ module Autoproj
|
|
38
85
|
def autoproj_gemfile_path; File.join(autoproj_install_dir, 'Gemfile') end
|
39
86
|
def autoproj_config_path; File.join(dot_autoproj, 'config.yml') end
|
40
87
|
|
88
|
+
# Whether we can access the network while installing
|
89
|
+
def local?; !!@local end
|
90
|
+
# (see #local?)
|
91
|
+
def local=(flag); @local = flag end
|
92
|
+
|
41
93
|
# Whether bundler should be installed locally in {#dot_autoproj}
|
42
94
|
def private_bundler?; @private_bundler end
|
95
|
+
# (see #private_bundler?)
|
96
|
+
def private_bundler=(flag); @private_bundler = flag end
|
43
97
|
# Whether autoproj should be installed locally in {#dot_autoproj}
|
44
98
|
def private_autoproj?; @private_autoproj end
|
99
|
+
# (see #private_autoproj?)
|
100
|
+
def private_autoproj=(flag); @private_autoproj = flag end
|
45
101
|
# Whether bundler should be installed locally in the workspace
|
46
102
|
# prefix directory
|
47
103
|
def private_gems?; @private_gems end
|
104
|
+
# (see #private_gems?)
|
105
|
+
def private_gems=(flag); @private_gems = flag end
|
48
106
|
|
49
107
|
def guess_gem_program
|
50
108
|
ruby_bin = RbConfig::CONFIG['RUBY_INSTALL_NAME']
|
@@ -68,14 +126,18 @@ module Autoproj
|
|
68
126
|
# @param [String] autoproj_version a constraint on the autoproj version
|
69
127
|
# that should be used
|
70
128
|
# @return [String]
|
71
|
-
def default_gemfile_contents(autoproj_version = ">= 0")
|
129
|
+
def default_gemfile_contents(autoproj_version = ">= 2.0.0.a")
|
72
130
|
["source \"https://rubygems.org\"",
|
73
|
-
"gem \"autoproj\", \"#{autoproj_version}\""
|
131
|
+
"gem \"autoproj\", \"#{autoproj_version}\"",
|
132
|
+
"gem \"utilrb\", \">= 3.0.0.a\""].join("\n")
|
74
133
|
end
|
75
134
|
|
76
135
|
# Parse the provided command line options and returns the non-options
|
77
136
|
def parse_options(args = ARGV)
|
78
137
|
options = OptionParser.new do |opt|
|
138
|
+
opt.on '--local', 'do not access the network (may fail)' do
|
139
|
+
@local = true
|
140
|
+
end
|
79
141
|
opt.on '--private-bundler', 'install bundler locally in the workspace' do
|
80
142
|
@private_bundler = true
|
81
143
|
end
|
@@ -104,28 +166,37 @@ module Autoproj
|
|
104
166
|
gem_program = guess_gem_program
|
105
167
|
puts "Detected 'gem' to be #{gem_program}"
|
106
168
|
|
169
|
+
local = ['--local'] if local?
|
170
|
+
|
107
171
|
result = system(
|
108
|
-
|
109
|
-
'GEM_HOME' => bundler_install_dir],
|
172
|
+
env_for_child.merge('GEM_PATH' => nil, 'GEM_HOME' => bundler_install_dir),
|
110
173
|
gem_program, 'install', '--no-document', '--no-user-install', '--no-format-executable',
|
174
|
+
*local,
|
111
175
|
"--bindir=#{File.join(bundler_install_dir, 'bin')}", 'bundler')
|
112
176
|
|
113
177
|
if !result
|
114
178
|
STDERR.puts "FATAL: failed to install bundler in #{dot_autoproj}"
|
115
179
|
exit 1
|
116
180
|
end
|
181
|
+
env['GEM_PATH'] << bundler_install_dir
|
182
|
+
env['PATH'] << File.join(bundler_install_dir, 'bin')
|
117
183
|
File.join(bin_dir, 'bundler')
|
118
184
|
end
|
119
185
|
|
120
186
|
def save_env_sh
|
121
187
|
env = Autobuild::Environment.new
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
188
|
+
env.prepare
|
189
|
+
|
190
|
+
%w{GEM_HOME GEM_PATH}.each do |name|
|
191
|
+
value = self.env[name]
|
192
|
+
if value.empty?
|
193
|
+
env.unset name
|
194
|
+
else
|
195
|
+
env.set name, *value
|
196
|
+
end
|
126
197
|
end
|
127
198
|
env.push_path 'PATH', File.join(autoproj_install_dir, 'bin')
|
128
|
-
|
199
|
+
|
129
200
|
if private_autoproj?
|
130
201
|
env.push_path 'GEM_PATH', autoproj_install_dir
|
131
202
|
end
|
@@ -149,7 +220,9 @@ export AUTOPROJ_CURRENT_ROOT=#{root_dir}
|
|
149
220
|
io.write gemfile
|
150
221
|
end
|
151
222
|
end
|
152
|
-
|
223
|
+
|
224
|
+
ENV_BUNDLE_GEMFILE_RX = /^(\s*ENV\[['"]BUNDLE_GEMFILE['"]\]\s*)(?:\|\|)?=/
|
225
|
+
|
153
226
|
def install_autoproj(bundler)
|
154
227
|
# Force bundler to update. If the user does not want this, let him specify a
|
155
228
|
# Gemfile with tighter version constraints
|
@@ -158,24 +231,57 @@ export AUTOPROJ_CURRENT_ROOT=#{root_dir}
|
|
158
231
|
FileUtils.rm lockfile
|
159
232
|
end
|
160
233
|
|
161
|
-
env = Hash['BUNDLE_GEMFILE' => nil, 'RUBYLIB' => nil]
|
162
234
|
opts = Array.new
|
235
|
+
opts << '--local' if local?
|
163
236
|
|
237
|
+
env = env_for_child
|
164
238
|
if private_autoproj?
|
165
|
-
env =
|
166
|
-
|
239
|
+
env = env.merge(
|
240
|
+
'GEM_PATH' => bundler_install_dir,
|
241
|
+
'GEM_HOME' => nil)
|
167
242
|
opts << "--clean" << "--path=#{autoproj_install_dir}"
|
168
243
|
end
|
169
244
|
|
245
|
+
binstubs_path = File.join(autoproj_install_dir, 'bin')
|
246
|
+
|
170
247
|
result = system(env,
|
171
|
-
bundler, 'install',
|
248
|
+
Gem.ruby, bundler, 'install',
|
172
249
|
"--gemfile=#{autoproj_gemfile_path}",
|
173
|
-
"--binstubs=#{
|
250
|
+
"--binstubs=#{binstubs_path}",
|
174
251
|
*opts)
|
175
252
|
if !result
|
176
253
|
STDERR.puts "FATAL: failed to install autoproj in #{dot_autoproj}"
|
177
254
|
exit 1
|
178
255
|
end
|
256
|
+
|
257
|
+
# Now tune the binstubs to force the usage of the autoproj
|
258
|
+
# gemfile. Otherwise, they get BUNDLE_GEMFILE from the
|
259
|
+
# environment by default
|
260
|
+
Dir.glob(File.join(binstubs_path, '*')) do |path|
|
261
|
+
next if !File.file?(path)
|
262
|
+
# Do NOT do that for bundler, otherwise it will fail with an
|
263
|
+
# "already loaded gemfile" message once we e.g. try to do
|
264
|
+
# 'bundler install --gemfile=NEW_GEMFILE'
|
265
|
+
next if File.basename(path) == 'bundler'
|
266
|
+
|
267
|
+
lines = File.readlines(path)
|
268
|
+
matched = false
|
269
|
+
filtered = lines.map do |l|
|
270
|
+
matched ||= (ENV_BUNDLE_GEMFILE_RX === l)
|
271
|
+
l.gsub(ENV_BUNDLE_GEMFILE_RX, '\\1=')
|
272
|
+
end
|
273
|
+
if !matched
|
274
|
+
raise UnexpectedBinstub, "expected #{path} to contain a line looking like ENV['BUNDLE_GEMFILE'] ||= but could not find one"
|
275
|
+
end
|
276
|
+
File.open(path, 'w') do |io|
|
277
|
+
io.write filtered.join("")
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
env['PATH'] << File.join(autoproj_install_dir, 'bin')
|
282
|
+
if private_autoproj?
|
283
|
+
env['GEM_PATH'] << autoproj_install_dir
|
284
|
+
end
|
179
285
|
end
|
180
286
|
|
181
287
|
def update_configuration
|
@@ -192,25 +298,92 @@ export AUTOPROJ_CURRENT_ROOT=#{root_dir}
|
|
192
298
|
end
|
193
299
|
end
|
194
300
|
|
301
|
+
def find_in_clean_path(command)
|
302
|
+
clean_path = env_for_child['PATH'].split(File::PATH_SEPARATOR)
|
303
|
+
clean_path.each do |p|
|
304
|
+
full_path = File.join(p, command)
|
305
|
+
if File.file?(full_path)
|
306
|
+
return full_path
|
307
|
+
end
|
308
|
+
end
|
309
|
+
nil
|
310
|
+
end
|
311
|
+
|
312
|
+
def find_bundler
|
313
|
+
clean_env = env_for_child
|
314
|
+
Gem.paths = Hash[
|
315
|
+
'GEM_HOME' => clean_env['GEM_HOME'] || Gem.default_dir,
|
316
|
+
'GEM_PATH' => clean_env['GEM_PATH'] || nil
|
317
|
+
]
|
318
|
+
# Here, we're getting into the esotheric
|
319
|
+
#
|
320
|
+
# The problem is that e.g. Ubuntu and Debian install an
|
321
|
+
# operating_system.rb file that sets proper OS defaults. Some
|
322
|
+
# autoproj installs have it in their RUBYLIB but should not
|
323
|
+
# because of limitations of autoproj 1.x. This leads to
|
324
|
+
# Gem.bindir being *not* valid for subprocesses
|
325
|
+
#
|
326
|
+
# So, we're calling 'gem' as a subcommand to discovery the
|
327
|
+
# actual bindir
|
328
|
+
bindir = IO.popen(clean_env, [Gem.ruby, '-e', 'puts Gem.bindir']).read
|
329
|
+
if bindir
|
330
|
+
env['PATH'].unshift bindir.chomp
|
331
|
+
else
|
332
|
+
STDERR.puts "FATAL: cannot run #{Gem.ruby} -e 'puts Gem.bindir'"
|
333
|
+
exit 1
|
334
|
+
end
|
335
|
+
|
336
|
+
bundler = find_in_clean_path('bundler')
|
337
|
+
if !bundler
|
338
|
+
clean_path = env_for_child['PATH']
|
339
|
+
STDERR.puts "FATAL: cannot find 'bundler' in PATH=#{clean_path}"
|
340
|
+
if ENV['PATH'] != clean_path
|
341
|
+
STDERR.puts " it appears that you already have some autoproj-generated env.sh loaded"
|
342
|
+
STDERR.puts " - if you are running 'autoproj upgrade', please contact the autoproj author at https://github.com/rock-core/autoproj/issues/new"
|
343
|
+
STDERR.puts " - if you are running an install, try again in a console where the env.sh is not loaded"
|
344
|
+
exit 1
|
345
|
+
else
|
346
|
+
STDERR.puts " the recommended action is to install it manually first by running 'gem install bundler'"
|
347
|
+
STDERR.puts " or call this command again with --private-bundler to have it installed in the workspace"
|
348
|
+
exit 1
|
349
|
+
end
|
350
|
+
end
|
351
|
+
bundler
|
352
|
+
end
|
353
|
+
|
195
354
|
def install
|
196
355
|
if private_bundler?
|
197
356
|
puts "Installing bundler in #{bundler_install_dir}"
|
198
357
|
bundler = install_bundler
|
358
|
+
else
|
359
|
+
bundler = find_bundler
|
360
|
+
puts "Detected bundler at #{bundler}"
|
199
361
|
end
|
200
362
|
save_gemfile
|
201
363
|
puts "Installing autoproj in #{dot_autoproj}"
|
202
|
-
install_autoproj(bundler
|
364
|
+
install_autoproj(bundler)
|
203
365
|
end
|
204
366
|
|
205
367
|
# Actually perform the install
|
206
|
-
def run
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
368
|
+
def run(stage2: false)
|
369
|
+
if stage2
|
370
|
+
require 'autobuild'
|
371
|
+
save_env_sh
|
372
|
+
else
|
373
|
+
install
|
374
|
+
|
375
|
+
env_for_child.each do |k, v|
|
376
|
+
if v
|
377
|
+
ENV[k] = v
|
378
|
+
else
|
379
|
+
ENV.delete(k)
|
380
|
+
end
|
381
|
+
end
|
382
|
+
ENV['BUNDLE_GEMFILE'] = autoproj_gemfile_path
|
383
|
+
update_configuration
|
384
|
+
exec Gem.ruby, File.join(autoproj_install_dir, 'bin', 'autoproj'),
|
385
|
+
'install-stage2', root_dir
|
386
|
+
end
|
214
387
|
end
|
215
388
|
end
|
216
389
|
end
|
@@ -219,5 +392,11 @@ end
|
|
219
392
|
|
220
393
|
|
221
394
|
ops = Autoproj::Ops::Install.new(Dir.pwd)
|
222
|
-
ops.parse_options(ARGV)
|
395
|
+
bootstrap_options = ops.parse_options(ARGV)
|
223
396
|
ops.run
|
397
|
+
|
398
|
+
# we assume that Install#run loads bundler and autobuild. Load autoproj and run
|
399
|
+
# bootstrap
|
400
|
+
require 'autoproj/cli/main'
|
401
|
+
Autoproj::CLI::Main.start(['bootstrap', *bootstrap_options])
|
402
|
+
|
data/bin/autoproj_bootstrap.in
CHANGED
@@ -8,5 +8,11 @@ end
|
|
8
8
|
AUTOPROJ_OPS_INSTALL
|
9
9
|
|
10
10
|
ops = Autoproj::Ops::Install.new(Dir.pwd)
|
11
|
-
ops.parse_options(ARGV)
|
11
|
+
bootstrap_options = ops.parse_options(ARGV)
|
12
12
|
ops.run
|
13
|
+
|
14
|
+
# we assume that Install#run loads bundler and autobuild. Load autoproj and run
|
15
|
+
# bootstrap
|
16
|
+
require 'autoproj/cli/main'
|
17
|
+
Autoproj::CLI::Main.start(['bootstrap', *bootstrap_options])
|
18
|
+
|
data/bin/autoproj_install
CHANGED
@@ -5,6 +5,7 @@ if RUBY_VERSION < "1.9.2"
|
|
5
5
|
exit 1
|
6
6
|
end
|
7
7
|
|
8
|
+
require 'pathname'
|
8
9
|
require 'optparse'
|
9
10
|
require 'fileutils'
|
10
11
|
require 'yaml'
|
@@ -17,19 +18,65 @@ module Autoproj
|
|
17
18
|
# It can be required standalone (i.e. does not depend on anything else than
|
18
19
|
# ruby and the ruby standard library)
|
19
20
|
class Install
|
21
|
+
class UnexpectedBinstub < RuntimeError; end
|
22
|
+
|
20
23
|
# The directory in which to install autoproj
|
21
24
|
attr_reader :root_dir
|
22
25
|
# Content of the Gemfile generated to install autoproj itself
|
23
26
|
attr_accessor :gemfile
|
27
|
+
# The environment that is passed to the bundler installs
|
28
|
+
attr_reader :env
|
24
29
|
|
25
30
|
def initialize(root_dir)
|
26
31
|
@root_dir = root_dir
|
27
|
-
|
32
|
+
if File.file?(autoproj_gemfile_path)
|
33
|
+
@gemfile = File.read(autoproj_gemfile_path)
|
34
|
+
else
|
35
|
+
@gemfile = default_gemfile_contents
|
36
|
+
end
|
37
|
+
|
28
38
|
@private_bundler = false
|
29
39
|
@private_autoproj = false
|
30
40
|
@private_gems = false
|
41
|
+
@local = false
|
42
|
+
@env = self.class.clean_env
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.clean_env
|
46
|
+
env = Hash.new
|
47
|
+
env['RUBYLIB'] = []
|
48
|
+
env['GEM_PATH'] = []
|
49
|
+
%w{PATH GEM_HOME}.each do |name|
|
50
|
+
env[name] = sanitize_env(ENV[name] || "")
|
51
|
+
end
|
52
|
+
env['BUNDLE_GEMFILE'] = nil
|
53
|
+
env
|
31
54
|
end
|
32
55
|
|
56
|
+
def env_for_child
|
57
|
+
env.inject(Hash.new) do |h, (k, v)|
|
58
|
+
h[k] = (v.join(File::PATH_SEPARATOR) if v && !v.empty?)
|
59
|
+
h
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.sanitize_env(value)
|
64
|
+
value.split(File::PATH_SEPARATOR).
|
65
|
+
find_all { |p| !in_workspace?(p) }
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.in_workspace?(base_dir)
|
69
|
+
path = Pathname.new(base_dir)
|
70
|
+
while !path.root?
|
71
|
+
if (path + ".autoproj").exist? || (path + "autoproj").exist?
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
path = path.parent
|
75
|
+
end
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
|
79
|
+
|
33
80
|
def dot_autoproj; File.join(root_dir, '.autoproj') end
|
34
81
|
def bin_dir; File.join(dot_autoproj, 'bin') end
|
35
82
|
def bundler_install_dir; File.join(dot_autoproj, 'bundler') end
|
@@ -38,13 +85,24 @@ module Autoproj
|
|
38
85
|
def autoproj_gemfile_path; File.join(autoproj_install_dir, 'Gemfile') end
|
39
86
|
def autoproj_config_path; File.join(dot_autoproj, 'config.yml') end
|
40
87
|
|
88
|
+
# Whether we can access the network while installing
|
89
|
+
def local?; !!@local end
|
90
|
+
# (see #local?)
|
91
|
+
def local=(flag); @local = flag end
|
92
|
+
|
41
93
|
# Whether bundler should be installed locally in {#dot_autoproj}
|
42
94
|
def private_bundler?; @private_bundler end
|
95
|
+
# (see #private_bundler?)
|
96
|
+
def private_bundler=(flag); @private_bundler = flag end
|
43
97
|
# Whether autoproj should be installed locally in {#dot_autoproj}
|
44
98
|
def private_autoproj?; @private_autoproj end
|
99
|
+
# (see #private_autoproj?)
|
100
|
+
def private_autoproj=(flag); @private_autoproj = flag end
|
45
101
|
# Whether bundler should be installed locally in the workspace
|
46
102
|
# prefix directory
|
47
103
|
def private_gems?; @private_gems end
|
104
|
+
# (see #private_gems?)
|
105
|
+
def private_gems=(flag); @private_gems = flag end
|
48
106
|
|
49
107
|
def guess_gem_program
|
50
108
|
ruby_bin = RbConfig::CONFIG['RUBY_INSTALL_NAME']
|
@@ -68,14 +126,18 @@ module Autoproj
|
|
68
126
|
# @param [String] autoproj_version a constraint on the autoproj version
|
69
127
|
# that should be used
|
70
128
|
# @return [String]
|
71
|
-
def default_gemfile_contents(autoproj_version = ">= 0")
|
129
|
+
def default_gemfile_contents(autoproj_version = ">= 2.0.0.a")
|
72
130
|
["source \"https://rubygems.org\"",
|
73
|
-
"gem \"autoproj\", \"#{autoproj_version}\""
|
131
|
+
"gem \"autoproj\", \"#{autoproj_version}\"",
|
132
|
+
"gem \"utilrb\", \">= 3.0.0.a\""].join("\n")
|
74
133
|
end
|
75
134
|
|
76
135
|
# Parse the provided command line options and returns the non-options
|
77
136
|
def parse_options(args = ARGV)
|
78
137
|
options = OptionParser.new do |opt|
|
138
|
+
opt.on '--local', 'do not access the network (may fail)' do
|
139
|
+
@local = true
|
140
|
+
end
|
79
141
|
opt.on '--private-bundler', 'install bundler locally in the workspace' do
|
80
142
|
@private_bundler = true
|
81
143
|
end
|
@@ -104,28 +166,37 @@ module Autoproj
|
|
104
166
|
gem_program = guess_gem_program
|
105
167
|
puts "Detected 'gem' to be #{gem_program}"
|
106
168
|
|
169
|
+
local = ['--local'] if local?
|
170
|
+
|
107
171
|
result = system(
|
108
|
-
|
109
|
-
'GEM_HOME' => bundler_install_dir],
|
172
|
+
env_for_child.merge('GEM_PATH' => nil, 'GEM_HOME' => bundler_install_dir),
|
110
173
|
gem_program, 'install', '--no-document', '--no-user-install', '--no-format-executable',
|
174
|
+
*local,
|
111
175
|
"--bindir=#{File.join(bundler_install_dir, 'bin')}", 'bundler')
|
112
176
|
|
113
177
|
if !result
|
114
178
|
STDERR.puts "FATAL: failed to install bundler in #{dot_autoproj}"
|
115
179
|
exit 1
|
116
180
|
end
|
181
|
+
env['GEM_PATH'] << bundler_install_dir
|
182
|
+
env['PATH'] << File.join(bundler_install_dir, 'bin')
|
117
183
|
File.join(bin_dir, 'bundler')
|
118
184
|
end
|
119
185
|
|
120
186
|
def save_env_sh
|
121
187
|
env = Autobuild::Environment.new
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
188
|
+
env.prepare
|
189
|
+
|
190
|
+
%w{GEM_HOME GEM_PATH}.each do |name|
|
191
|
+
value = self.env[name]
|
192
|
+
if value.empty?
|
193
|
+
env.unset name
|
194
|
+
else
|
195
|
+
env.set name, *value
|
196
|
+
end
|
126
197
|
end
|
127
198
|
env.push_path 'PATH', File.join(autoproj_install_dir, 'bin')
|
128
|
-
|
199
|
+
|
129
200
|
if private_autoproj?
|
130
201
|
env.push_path 'GEM_PATH', autoproj_install_dir
|
131
202
|
end
|
@@ -149,7 +220,9 @@ export AUTOPROJ_CURRENT_ROOT=#{root_dir}
|
|
149
220
|
io.write gemfile
|
150
221
|
end
|
151
222
|
end
|
152
|
-
|
223
|
+
|
224
|
+
ENV_BUNDLE_GEMFILE_RX = /^(\s*ENV\[['"]BUNDLE_GEMFILE['"]\]\s*)(?:\|\|)?=/
|
225
|
+
|
153
226
|
def install_autoproj(bundler)
|
154
227
|
# Force bundler to update. If the user does not want this, let him specify a
|
155
228
|
# Gemfile with tighter version constraints
|
@@ -158,24 +231,57 @@ export AUTOPROJ_CURRENT_ROOT=#{root_dir}
|
|
158
231
|
FileUtils.rm lockfile
|
159
232
|
end
|
160
233
|
|
161
|
-
env = Hash['BUNDLE_GEMFILE' => nil, 'RUBYLIB' => nil]
|
162
234
|
opts = Array.new
|
235
|
+
opts << '--local' if local?
|
163
236
|
|
237
|
+
env = env_for_child
|
164
238
|
if private_autoproj?
|
165
|
-
env =
|
166
|
-
|
239
|
+
env = env.merge(
|
240
|
+
'GEM_PATH' => bundler_install_dir,
|
241
|
+
'GEM_HOME' => nil)
|
167
242
|
opts << "--clean" << "--path=#{autoproj_install_dir}"
|
168
243
|
end
|
169
244
|
|
245
|
+
binstubs_path = File.join(autoproj_install_dir, 'bin')
|
246
|
+
|
170
247
|
result = system(env,
|
171
|
-
bundler, 'install',
|
248
|
+
Gem.ruby, bundler, 'install',
|
172
249
|
"--gemfile=#{autoproj_gemfile_path}",
|
173
|
-
"--binstubs=#{
|
250
|
+
"--binstubs=#{binstubs_path}",
|
174
251
|
*opts)
|
175
252
|
if !result
|
176
253
|
STDERR.puts "FATAL: failed to install autoproj in #{dot_autoproj}"
|
177
254
|
exit 1
|
178
255
|
end
|
256
|
+
|
257
|
+
# Now tune the binstubs to force the usage of the autoproj
|
258
|
+
# gemfile. Otherwise, they get BUNDLE_GEMFILE from the
|
259
|
+
# environment by default
|
260
|
+
Dir.glob(File.join(binstubs_path, '*')) do |path|
|
261
|
+
next if !File.file?(path)
|
262
|
+
# Do NOT do that for bundler, otherwise it will fail with an
|
263
|
+
# "already loaded gemfile" message once we e.g. try to do
|
264
|
+
# 'bundler install --gemfile=NEW_GEMFILE'
|
265
|
+
next if File.basename(path) == 'bundler'
|
266
|
+
|
267
|
+
lines = File.readlines(path)
|
268
|
+
matched = false
|
269
|
+
filtered = lines.map do |l|
|
270
|
+
matched ||= (ENV_BUNDLE_GEMFILE_RX === l)
|
271
|
+
l.gsub(ENV_BUNDLE_GEMFILE_RX, '\\1=')
|
272
|
+
end
|
273
|
+
if !matched
|
274
|
+
raise UnexpectedBinstub, "expected #{path} to contain a line looking like ENV['BUNDLE_GEMFILE'] ||= but could not find one"
|
275
|
+
end
|
276
|
+
File.open(path, 'w') do |io|
|
277
|
+
io.write filtered.join("")
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
env['PATH'] << File.join(autoproj_install_dir, 'bin')
|
282
|
+
if private_autoproj?
|
283
|
+
env['GEM_PATH'] << autoproj_install_dir
|
284
|
+
end
|
179
285
|
end
|
180
286
|
|
181
287
|
def update_configuration
|
@@ -192,25 +298,92 @@ export AUTOPROJ_CURRENT_ROOT=#{root_dir}
|
|
192
298
|
end
|
193
299
|
end
|
194
300
|
|
301
|
+
def find_in_clean_path(command)
|
302
|
+
clean_path = env_for_child['PATH'].split(File::PATH_SEPARATOR)
|
303
|
+
clean_path.each do |p|
|
304
|
+
full_path = File.join(p, command)
|
305
|
+
if File.file?(full_path)
|
306
|
+
return full_path
|
307
|
+
end
|
308
|
+
end
|
309
|
+
nil
|
310
|
+
end
|
311
|
+
|
312
|
+
def find_bundler
|
313
|
+
clean_env = env_for_child
|
314
|
+
Gem.paths = Hash[
|
315
|
+
'GEM_HOME' => clean_env['GEM_HOME'] || Gem.default_dir,
|
316
|
+
'GEM_PATH' => clean_env['GEM_PATH'] || nil
|
317
|
+
]
|
318
|
+
# Here, we're getting into the esotheric
|
319
|
+
#
|
320
|
+
# The problem is that e.g. Ubuntu and Debian install an
|
321
|
+
# operating_system.rb file that sets proper OS defaults. Some
|
322
|
+
# autoproj installs have it in their RUBYLIB but should not
|
323
|
+
# because of limitations of autoproj 1.x. This leads to
|
324
|
+
# Gem.bindir being *not* valid for subprocesses
|
325
|
+
#
|
326
|
+
# So, we're calling 'gem' as a subcommand to discovery the
|
327
|
+
# actual bindir
|
328
|
+
bindir = IO.popen(clean_env, [Gem.ruby, '-e', 'puts Gem.bindir']).read
|
329
|
+
if bindir
|
330
|
+
env['PATH'].unshift bindir.chomp
|
331
|
+
else
|
332
|
+
STDERR.puts "FATAL: cannot run #{Gem.ruby} -e 'puts Gem.bindir'"
|
333
|
+
exit 1
|
334
|
+
end
|
335
|
+
|
336
|
+
bundler = find_in_clean_path('bundler')
|
337
|
+
if !bundler
|
338
|
+
clean_path = env_for_child['PATH']
|
339
|
+
STDERR.puts "FATAL: cannot find 'bundler' in PATH=#{clean_path}"
|
340
|
+
if ENV['PATH'] != clean_path
|
341
|
+
STDERR.puts " it appears that you already have some autoproj-generated env.sh loaded"
|
342
|
+
STDERR.puts " - if you are running 'autoproj upgrade', please contact the autoproj author at https://github.com/rock-core/autoproj/issues/new"
|
343
|
+
STDERR.puts " - if you are running an install, try again in a console where the env.sh is not loaded"
|
344
|
+
exit 1
|
345
|
+
else
|
346
|
+
STDERR.puts " the recommended action is to install it manually first by running 'gem install bundler'"
|
347
|
+
STDERR.puts " or call this command again with --private-bundler to have it installed in the workspace"
|
348
|
+
exit 1
|
349
|
+
end
|
350
|
+
end
|
351
|
+
bundler
|
352
|
+
end
|
353
|
+
|
195
354
|
def install
|
196
355
|
if private_bundler?
|
197
356
|
puts "Installing bundler in #{bundler_install_dir}"
|
198
357
|
bundler = install_bundler
|
358
|
+
else
|
359
|
+
bundler = find_bundler
|
360
|
+
puts "Detected bundler at #{bundler}"
|
199
361
|
end
|
200
362
|
save_gemfile
|
201
363
|
puts "Installing autoproj in #{dot_autoproj}"
|
202
|
-
install_autoproj(bundler
|
364
|
+
install_autoproj(bundler)
|
203
365
|
end
|
204
366
|
|
205
367
|
# Actually perform the install
|
206
|
-
def run
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
368
|
+
def run(stage2: false)
|
369
|
+
if stage2
|
370
|
+
require 'autobuild'
|
371
|
+
save_env_sh
|
372
|
+
else
|
373
|
+
install
|
374
|
+
|
375
|
+
env_for_child.each do |k, v|
|
376
|
+
if v
|
377
|
+
ENV[k] = v
|
378
|
+
else
|
379
|
+
ENV.delete(k)
|
380
|
+
end
|
381
|
+
end
|
382
|
+
ENV['BUNDLE_GEMFILE'] = autoproj_gemfile_path
|
383
|
+
update_configuration
|
384
|
+
exec Gem.ruby, File.join(autoproj_install_dir, 'bin', 'autoproj'),
|
385
|
+
'install-stage2', root_dir
|
386
|
+
end
|
214
387
|
end
|
215
388
|
end
|
216
389
|
end
|