autoproj 2.0.0.rc4 → 2.0.0.rc5
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.
- 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
|