autoproj 2.11.0 → 2.14.0
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/.rubocop.yml +5 -8
- data/.travis.yml +5 -3
- data/autoproj.gemspec +6 -6
- data/bin/alog +1 -0
- data/bin/autoproj +1 -1
- data/bin/autoproj_bootstrap +130 -67
- data/bin/autoproj_bootstrap.in +9 -7
- data/bin/autoproj_install +129 -63
- data/bin/autoproj_install.in +8 -3
- data/lib/autoproj/autobuild_extensions/dsl.rb +27 -12
- data/lib/autoproj/base.rb +18 -0
- data/lib/autoproj/cli/base.rb +1 -1
- data/lib/autoproj/cli/build.rb +8 -3
- data/lib/autoproj/cli/cache.rb +79 -7
- data/lib/autoproj/cli/inspection_tool.rb +5 -6
- data/lib/autoproj/cli/main.rb +33 -9
- data/lib/autoproj/cli/show.rb +12 -18
- data/lib/autoproj/cli/status.rb +15 -9
- data/lib/autoproj/cli/test.rb +1 -1
- data/lib/autoproj/cli/update.rb +72 -17
- data/lib/autoproj/cli/utility.rb +25 -28
- data/lib/autoproj/configuration.rb +15 -4
- data/lib/autoproj/default.osdeps +29 -3
- data/lib/autoproj/environment.rb +17 -13
- data/lib/autoproj/installation_manifest.rb +7 -5
- data/lib/autoproj/manifest.rb +14 -6
- data/lib/autoproj/ops/build.rb +23 -21
- data/lib/autoproj/ops/cache.rb +151 -33
- data/lib/autoproj/ops/cached_env.rb +2 -2
- data/lib/autoproj/ops/import.rb +23 -4
- data/lib/autoproj/ops/install.rb +121 -60
- data/lib/autoproj/ops/phase_reporting.rb +49 -0
- data/lib/autoproj/ops/snapshot.rb +2 -1
- data/lib/autoproj/ops/tools.rb +2 -2
- data/lib/autoproj/os_package_installer.rb +19 -11
- data/lib/autoproj/package_definition.rb +1 -1
- data/lib/autoproj/package_managers/apt_dpkg_manager.rb +49 -28
- data/lib/autoproj/package_managers/bundler_manager.rb +102 -19
- data/lib/autoproj/package_managers/homebrew_manager.rb +2 -2
- data/lib/autoproj/package_managers/pip_manager.rb +34 -22
- data/lib/autoproj/package_managers/shell_script_manager.rb +44 -24
- data/lib/autoproj/package_manifest.rb +43 -31
- data/lib/autoproj/package_set.rb +2 -2
- data/lib/autoproj/python.rb +285 -0
- data/lib/autoproj/test.rb +26 -10
- data/lib/autoproj/variable_expansion.rb +3 -1
- data/lib/autoproj/vcs_definition.rb +25 -12
- data/lib/autoproj/version.rb +1 -1
- data/lib/autoproj/workspace.rb +60 -16
- data/lib/autoproj.rb +3 -0
- metadata +17 -28
data/lib/autoproj/manifest.rb
CHANGED
@@ -50,12 +50,19 @@ module Autoproj
|
|
50
50
|
|
51
51
|
# Load the manifest data contained in +file+
|
52
52
|
def load(file)
|
53
|
-
|
54
|
-
raise ConfigError.new(File.dirname(file)),
|
53
|
+
unless File.exist?(file)
|
54
|
+
raise ConfigError.new(File.dirname(file)),
|
55
|
+
"expected an autoproj configuration in #{File.dirname(file)}, "\
|
56
|
+
"but #{file} does not exist"
|
55
57
|
end
|
56
58
|
|
57
59
|
data = Autoproj.in_file(file, Autoproj::YAML_LOAD_ERROR) do
|
58
|
-
YAML.
|
60
|
+
YAML.safe_load(File.read(file)) || {}
|
61
|
+
end
|
62
|
+
|
63
|
+
if data["layout"]&.member?(nil)
|
64
|
+
Autoproj.warn "There is an empty entry in your layout in #{file}. All empty entries are ignored."
|
65
|
+
data["layout"] = data["layout"].compact
|
59
66
|
end
|
60
67
|
|
61
68
|
@file = file
|
@@ -81,7 +88,8 @@ module Autoproj
|
|
81
88
|
@has_layout = !!data['layout']
|
82
89
|
|
83
90
|
if data['constants']
|
84
|
-
@constant_definitions =
|
91
|
+
@constant_definitions =
|
92
|
+
Autoproj.resolve_constant_definitions(data['constants'])
|
85
93
|
end
|
86
94
|
end
|
87
95
|
|
@@ -1234,7 +1242,7 @@ module Autoproj
|
|
1234
1242
|
workspace.config
|
1235
1243
|
end
|
1236
1244
|
|
1237
|
-
def self.add_osdeps_overrides(*args, &block)
|
1238
|
-
manifest.add_osdeps_overrides(*args, &block)
|
1245
|
+
def self.add_osdeps_overrides(*args, **kw, &block)
|
1246
|
+
manifest.add_osdeps_overrides(*args, **kw, &block)
|
1239
1247
|
end
|
1240
1248
|
end
|
data/lib/autoproj/ops/build.rb
CHANGED
@@ -87,34 +87,36 @@ module Autoproj
|
|
87
87
|
# names of the packages that should be rebuilt
|
88
88
|
# @return [void]
|
89
89
|
def build_packages(all_enabled_packages, options = Hash.new)
|
90
|
+
if @report_path
|
91
|
+
reporting = Ops::PhaseReporting.new(
|
92
|
+
'build', @report_path, method(:package_metadata)
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
90
96
|
Autobuild.do_rebuild = false
|
91
97
|
Autobuild.do_forced_build = false
|
98
|
+
reporting&.initialize_incremental_report
|
92
99
|
begin
|
93
|
-
Autobuild.apply(
|
100
|
+
Autobuild.apply(
|
101
|
+
all_enabled_packages,
|
102
|
+
"autoproj-build", ['build'], options
|
103
|
+
) do |pkg, phase|
|
104
|
+
reporting&.report_incremental(pkg) if phase == 'build'
|
105
|
+
end
|
106
|
+
|
94
107
|
ensure
|
95
|
-
|
108
|
+
packages = all_enabled_packages.map do |name|
|
109
|
+
@manifest.find_autobuild_package(name)
|
110
|
+
end
|
111
|
+
reporting&.create_report(packages)
|
96
112
|
end
|
97
113
|
end
|
98
114
|
|
99
|
-
def
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
h[pkg.name] = {
|
106
|
-
invoked: !!pkg.install_invoked?,
|
107
|
-
success: !!pkg.installed?
|
108
|
-
}
|
109
|
-
end
|
110
|
-
|
111
|
-
report = JSON.pretty_generate({
|
112
|
-
build_report: {
|
113
|
-
timestamp: Time.now,
|
114
|
-
packages: packages
|
115
|
-
}
|
116
|
-
})
|
117
|
-
IO.write(@report_path, report)
|
115
|
+
def package_metadata(autobuild_package)
|
116
|
+
{
|
117
|
+
invoked: !!autobuild_package.install_invoked?,
|
118
|
+
success: !!autobuild_package.installed?
|
119
|
+
}
|
118
120
|
end
|
119
121
|
end
|
120
122
|
end
|
data/lib/autoproj/ops/cache.rb
CHANGED
@@ -4,9 +4,10 @@ module Autoproj
|
|
4
4
|
attr_reader :cache_dir
|
5
5
|
attr_reader :manifest
|
6
6
|
|
7
|
-
def initialize(cache_dir,
|
7
|
+
def initialize(cache_dir, ws)
|
8
8
|
@cache_dir = cache_dir
|
9
|
-
@
|
9
|
+
@ws = ws
|
10
|
+
@manifest = ws.manifest
|
10
11
|
end
|
11
12
|
|
12
13
|
def with_retry(count)
|
@@ -27,29 +28,39 @@ module Autoproj
|
|
27
28
|
File.join(cache_dir, 'git')
|
28
29
|
end
|
29
30
|
|
30
|
-
def cache_git(pkg,
|
31
|
+
def cache_git(pkg, checkout_only: false)
|
31
32
|
pkg.importdir = File.join(git_cache_dir, pkg.name)
|
32
|
-
if
|
33
|
-
return
|
34
|
-
end
|
33
|
+
return if checkout_only && File.directory?(pkg.importdir)
|
35
34
|
|
36
35
|
pkg.importer.local_branch = nil
|
37
36
|
pkg.importer.remote_branch = nil
|
38
37
|
pkg.importer.remote_name = 'autobuild'
|
39
38
|
|
40
|
-
|
39
|
+
unless File.directory?(pkg.importdir)
|
41
40
|
FileUtils.mkdir_p File.dirname(pkg.importdir)
|
42
|
-
Autobuild::Subprocess.run(
|
41
|
+
Autobuild::Subprocess.run(
|
42
|
+
"autoproj-cache", "import", Autobuild.tool(:git),
|
43
|
+
"--git-dir", pkg.importdir, 'init', "--bare"
|
44
|
+
)
|
43
45
|
end
|
44
46
|
pkg.importer.update_remotes_configuration(pkg)
|
45
47
|
|
46
48
|
with_retry(10) do
|
47
|
-
Autobuild::Subprocess.run(
|
49
|
+
Autobuild::Subprocess.run(
|
50
|
+
'autoproj-cache', :import, Autobuild.tool('git'),
|
51
|
+
'--git-dir', pkg.importdir, 'remote', 'update', 'autobuild'
|
52
|
+
)
|
48
53
|
end
|
49
54
|
with_retry(10) do
|
50
|
-
Autobuild::Subprocess.run(
|
55
|
+
Autobuild::Subprocess.run(
|
56
|
+
'autoproj-cache', :import, Autobuild.tool('git'),
|
57
|
+
'--git-dir', pkg.importdir, 'fetch', 'autobuild', '--tags'
|
58
|
+
)
|
51
59
|
end
|
52
|
-
Autobuild::Subprocess.run(
|
60
|
+
Autobuild::Subprocess.run(
|
61
|
+
'autoproj-cache', :import, Autobuild.tool('git'),
|
62
|
+
'--git-dir', pkg.importdir, 'gc', '--prune=all'
|
63
|
+
)
|
53
64
|
end
|
54
65
|
|
55
66
|
def archive_cache_dir
|
@@ -63,7 +74,8 @@ module Autoproj
|
|
63
74
|
end
|
64
75
|
end
|
65
76
|
|
66
|
-
def create_or_update(*package_names, all: true, keep_going: false,
|
77
|
+
def create_or_update(*package_names, all: true, keep_going: false,
|
78
|
+
checkout_only: false)
|
67
79
|
FileUtils.mkdir_p cache_dir
|
68
80
|
|
69
81
|
if package_names.empty?
|
@@ -75,7 +87,7 @@ module Autoproj
|
|
75
87
|
end
|
76
88
|
else
|
77
89
|
packages = package_names.map do |name|
|
78
|
-
if pkg = manifest.find_autobuild_package(name)
|
90
|
+
if (pkg = manifest.find_autobuild_package(name))
|
79
91
|
pkg
|
80
92
|
else
|
81
93
|
raise PackageNotFound, "no package named #{name}"
|
@@ -88,42 +100,148 @@ module Autoproj
|
|
88
100
|
total = packages.size
|
89
101
|
Autoproj.message "Handling #{total} packages"
|
90
102
|
packages.each_with_index do |pkg, i|
|
91
|
-
|
103
|
+
# No need to process this one, it is uses another package's
|
104
|
+
# import
|
105
|
+
next if pkg.srcdir != pkg.importdir
|
106
|
+
|
92
107
|
begin
|
93
108
|
case pkg.importer
|
94
109
|
when Autobuild::Git
|
95
|
-
Autoproj.message
|
110
|
+
Autoproj.message(
|
111
|
+
" [#{i}/#{total}] caching #{pkg.name} (git)"
|
112
|
+
)
|
96
113
|
cache_git(pkg, checkout_only: checkout_only)
|
97
114
|
when Autobuild::ArchiveImporter
|
98
|
-
Autoproj.message
|
115
|
+
Autoproj.message(
|
116
|
+
" [#{i}/#{total}] caching #{pkg.name} (archive)"
|
117
|
+
)
|
99
118
|
cache_archive(pkg)
|
100
119
|
else
|
101
|
-
Autoproj.message
|
120
|
+
Autoproj.message(
|
121
|
+
" [#{i}/#{total}] not caching #{pkg.name} "\
|
122
|
+
"(cannot cache #{pkg.importer.class})"
|
123
|
+
)
|
102
124
|
end
|
103
125
|
rescue Interrupt
|
104
126
|
raise
|
105
127
|
rescue ::Exception => e
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
pkg.message(
|
116
|
-
|
117
|
-
|
128
|
+
raise unless keep_going
|
129
|
+
|
130
|
+
pkg.error " failed to cache #{pkg.name}, "\
|
131
|
+
'but going on as requested'
|
132
|
+
lines = e.to_s.split('\n')
|
133
|
+
lines = e.message.split('\n') if lines.empty?
|
134
|
+
lines = ['unknown error'] if lines.empty?
|
135
|
+
pkg.message(lines.shift, :red, :bold)
|
136
|
+
lines.each do |line|
|
137
|
+
pkg.message(line)
|
138
|
+
end
|
139
|
+
nil
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def gems_cache_dir
|
145
|
+
File.join(cache_dir, 'package_managers', 'gem')
|
146
|
+
end
|
147
|
+
|
148
|
+
def create_or_update_gems(keep_going: true, compile_force: false, compile: [])
|
149
|
+
# Note: this might directly copy into the cache directoy, and
|
150
|
+
# we support it later
|
151
|
+
cache_dir = File.join(@ws.prefix_dir, 'gems', 'vendor', 'cache')
|
152
|
+
PackageManagers::BundlerManager.run_bundler(
|
153
|
+
@ws, 'cache'
|
154
|
+
)
|
155
|
+
|
156
|
+
FileUtils.mkdir_p(gems_cache_dir) unless File.exist?(gems_cache_dir)
|
157
|
+
|
158
|
+
needs_copy =
|
159
|
+
if File.exist?(cache_dir)
|
160
|
+
real_cache_dir = File.realpath(cache_dir)
|
161
|
+
real_target_dir = File.realpath(gems_cache_dir)
|
162
|
+
(real_cache_dir != real_target_dir)
|
163
|
+
end
|
164
|
+
|
165
|
+
synchronize_gems_cache_dirs(real_cache_dir, real_target_dir) if needs_copy
|
166
|
+
|
167
|
+
platform_suffix = "-#{Gem::Platform.local}.gem"
|
168
|
+
failed = []
|
169
|
+
compile.each do |gem_name, artifacts: []|
|
170
|
+
Dir.glob(File.join(cache_dir, "#{gem_name}*.gem")) do |gem|
|
171
|
+
next if gem.end_with?(platform_suffix)
|
172
|
+
|
173
|
+
gem_basename = File.basename(gem, ".gem")
|
174
|
+
expected_platform_gem = File.join(
|
175
|
+
real_target_dir, "#{gem_basename}#{platform_suffix}"
|
176
|
+
)
|
177
|
+
next if !compile_force && File.file?(expected_platform_gem)
|
178
|
+
|
179
|
+
begin
|
180
|
+
compile_gem(
|
181
|
+
gem, artifacts: artifacts, output: real_target_dir
|
182
|
+
)
|
183
|
+
rescue CompilationFailed
|
184
|
+
unless keep_going
|
185
|
+
raise CompilationFailed, "#{gem} failed to compile"
|
118
186
|
end
|
119
|
-
|
120
|
-
|
121
|
-
raise
|
187
|
+
|
188
|
+
failed << gem
|
122
189
|
end
|
123
190
|
end
|
124
191
|
end
|
192
|
+
|
193
|
+
unless failed.empty?
|
194
|
+
raise CompilationFailed, "#{failed.sort.join(', ')} failed to compile"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
class CompilationFailed < RuntimeError; end
|
199
|
+
|
200
|
+
def synchronize_gems_cache_dirs(source, target)
|
201
|
+
Dir.glob(File.join(source, "*.gem")) do |source_file|
|
202
|
+
basename = File.basename(source_file)
|
203
|
+
target_file = File.join(target, basename)
|
204
|
+
next if File.file?(target_file)
|
205
|
+
|
206
|
+
Autoproj.message "gems: caching #{basename}"
|
207
|
+
FileUtils.cp source_file, target_file
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def guess_gem_program
|
212
|
+
return Autobuild.programs['gem'] if Autobuild.programs['gem']
|
213
|
+
|
214
|
+
ruby_bin = RbConfig::CONFIG['RUBY_INSTALL_NAME']
|
215
|
+
ruby_bindir = RbConfig::CONFIG['bindir']
|
216
|
+
|
217
|
+
candidates = ['gem']
|
218
|
+
candidates << "gem#{$1}" if ruby_bin =~ /^ruby(.+)$/
|
219
|
+
|
220
|
+
candidates.each do |gem_name|
|
221
|
+
if File.file?(gem_full_path = File.join(ruby_bindir, gem_name))
|
222
|
+
Autobuild.programs['gem'] = gem_full_path
|
223
|
+
return Autobuild.programs['gem']
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
raise ArgumentError,
|
228
|
+
'cannot find a gem program (tried '\
|
229
|
+
"#{candidates.sort.join(', ')} in #{ruby_bindir})"
|
230
|
+
end
|
231
|
+
|
232
|
+
private def compile_gem(gem_path, output:, artifacts: [])
|
233
|
+
artifacts = artifacts.flat_map do |include, n|
|
234
|
+
if include
|
235
|
+
["--include", n]
|
236
|
+
else
|
237
|
+
["--exclude", n]
|
238
|
+
end
|
239
|
+
end
|
240
|
+
unless system(Autobuild.tool('ruby'), '-S', guess_gem_program,
|
241
|
+
'compile', '--output', output, *artifacts, gem_path)
|
242
|
+
raise CompilationFailed, "#{gem_path} failed to compile"
|
243
|
+
end
|
125
244
|
end
|
126
245
|
end
|
127
246
|
end
|
128
247
|
end
|
129
|
-
|
@@ -9,7 +9,7 @@ module Autoproj
|
|
9
9
|
def self.load_cached_env(root_dir)
|
10
10
|
path = cached_env_path(root_dir)
|
11
11
|
if File.file?(path)
|
12
|
-
env = YAML.
|
12
|
+
env = YAML.safe_load(File.read(path))
|
13
13
|
Autobuild::Environment::ExportedEnvironment.new(
|
14
14
|
env['set'], env['unset'], env['update'])
|
15
15
|
end
|
@@ -20,7 +20,7 @@ module Autoproj
|
|
20
20
|
path = cached_env_path(root_dir)
|
21
21
|
existing =
|
22
22
|
begin
|
23
|
-
YAML.
|
23
|
+
YAML.safe_load(File.read(path))
|
24
24
|
rescue Exception
|
25
25
|
end
|
26
26
|
|
data/lib/autoproj/ops/import.rb
CHANGED
@@ -199,6 +199,7 @@ module Autoproj
|
|
199
199
|
install_vcs_packages: Hash.new,
|
200
200
|
non_imported_packages: :checkout,
|
201
201
|
auto_exclude: auto_exclude?,
|
202
|
+
filter: ->(package) { true },
|
202
203
|
**import_options)
|
203
204
|
|
204
205
|
unless %i[checkout ignore return].include?(non_imported_packages)
|
@@ -235,6 +236,11 @@ module Autoproj
|
|
235
236
|
missing_vcs = Array.new
|
236
237
|
installed_vcs_packages = Set['none', 'local']
|
237
238
|
while failures.empty? || keep_going
|
239
|
+
# Allow 'filter' to parallelize as well
|
240
|
+
if filter.respond_to?(:lookahead)
|
241
|
+
package_queue.each { |pkg| filter.lookahead(pkg) }
|
242
|
+
end
|
243
|
+
|
238
244
|
# Queue work for all packages in the queue
|
239
245
|
package_queue.each do |pkg|
|
240
246
|
# Remove packages that have already been processed
|
@@ -255,6 +261,11 @@ module Autoproj
|
|
255
261
|
end
|
256
262
|
all_processed_packages << pkg
|
257
263
|
|
264
|
+
unless filter.call(pkg)
|
265
|
+
completion_queue << [pkg, Time.now]
|
266
|
+
next
|
267
|
+
end
|
268
|
+
|
258
269
|
importer = pkg.autobuild.importer
|
259
270
|
if !pre_package_import(selection, manifest, pkg.autobuild,
|
260
271
|
reverse_dependencies)
|
@@ -272,8 +283,8 @@ module Autoproj
|
|
272
283
|
next
|
273
284
|
end
|
274
285
|
|
275
|
-
pending_packages << pkg
|
276
286
|
begin
|
287
|
+
pending_packages << pkg
|
277
288
|
queue_import_work(
|
278
289
|
executor, completion_queue, pkg,
|
279
290
|
retry_count: retry_count,
|
@@ -288,8 +299,12 @@ module Autoproj
|
|
288
299
|
if completion_queue.empty? && pending_packages.empty?
|
289
300
|
unless missing_vcs.empty?
|
290
301
|
installed_vcs_packages.merge(
|
291
|
-
install_vcs_packages_for(
|
292
|
-
|
302
|
+
install_vcs_packages_for(
|
303
|
+
*missing_vcs,
|
304
|
+
install_only: import_options[:checkout_only],
|
305
|
+
**install_vcs_packages
|
306
|
+
)
|
307
|
+
)
|
293
308
|
package_queue.concat(missing_vcs)
|
294
309
|
missing_vcs.clear
|
295
310
|
next
|
@@ -366,7 +381,9 @@ module Autoproj
|
|
366
381
|
end
|
367
382
|
end
|
368
383
|
|
369
|
-
def finalize_package_load(processed_packages,
|
384
|
+
def finalize_package_load(processed_packages,
|
385
|
+
ignore_optional_dependencies: false,
|
386
|
+
auto_exclude: auto_exclude?)
|
370
387
|
manifest = ws.manifest
|
371
388
|
|
372
389
|
all = Set.new
|
@@ -426,6 +443,7 @@ module Autoproj
|
|
426
443
|
keep_going: false,
|
427
444
|
install_vcs_packages: Hash.new,
|
428
445
|
auto_exclude: auto_exclude?,
|
446
|
+
filter: ->(pkg) { true },
|
429
447
|
**import_options)
|
430
448
|
|
431
449
|
manifest = ws.manifest
|
@@ -437,6 +455,7 @@ module Autoproj
|
|
437
455
|
recursive: recursive,
|
438
456
|
install_vcs_packages: install_vcs_packages,
|
439
457
|
auto_exclude: auto_exclude,
|
458
|
+
filter: filter,
|
440
459
|
**import_options)
|
441
460
|
|
442
461
|
raise failures.first if !keep_going && !failures.empty?
|
data/lib/autoproj/ops/install.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'pathname'
|
2
4
|
require 'optparse'
|
3
5
|
require 'fileutils'
|
4
6
|
require 'yaml'
|
7
|
+
require 'English'
|
5
8
|
|
6
9
|
module Autoproj
|
7
10
|
module Ops
|
@@ -13,6 +16,36 @@ module Autoproj
|
|
13
16
|
class Install
|
14
17
|
class UnexpectedBinstub < RuntimeError; end
|
15
18
|
|
19
|
+
RUBYLIB_REINIT = <<~RUBY
|
20
|
+
if defined?(Bundler)
|
21
|
+
if Bundler.respond_to?(:with_unbundled_env)
|
22
|
+
Bundler.with_unbundled_env do
|
23
|
+
exec(Hash['RUBYLIB' => nil], $0, *ARGV)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
Bundler.with_clean_env do
|
27
|
+
exec(Hash['RUBYLIB' => nil], $0, *ARGV)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
elsif ENV['RUBYLIB']
|
31
|
+
exec(Hash['RUBYLIB' => nil], $0, *ARGV)
|
32
|
+
end
|
33
|
+
RUBY
|
34
|
+
|
35
|
+
WITHOUT_BUNDLER = <<~RUBY
|
36
|
+
if defined?(Bundler)
|
37
|
+
if Bundler.respond_to?(:with_unbundled_env)
|
38
|
+
Bundler.with_unbundled_env do
|
39
|
+
exec($0, *ARGV)
|
40
|
+
end
|
41
|
+
else
|
42
|
+
Bundler.with_clean_env do
|
43
|
+
exec($0, *ARGV)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
RUBY
|
48
|
+
|
16
49
|
# The created workspace's root directory
|
17
50
|
attr_reader :root_dir
|
18
51
|
# Content of the Gemfile generated to install autoproj itself
|
@@ -220,6 +253,10 @@ module Autoproj
|
|
220
253
|
"gem \"utilrb\", \">= 3.0.1\""].join("\n")
|
221
254
|
end
|
222
255
|
|
256
|
+
def add_seed_config(path)
|
257
|
+
@config.merge!(YAML.safe_load(File.read(path), [Symbol]))
|
258
|
+
end
|
259
|
+
|
223
260
|
# Parse the provided command line options and returns the non-options
|
224
261
|
def parse_options(args = ARGV)
|
225
262
|
options = OptionParser.new do |opt|
|
@@ -243,6 +280,10 @@ module Autoproj
|
|
243
280
|
opt.on '--public-gems', "install gems in the default gem location" do
|
244
281
|
self.install_gems_in_gem_user_dir
|
245
282
|
end
|
283
|
+
opt.on '--bundler-version=VERSION_CONSTRAINT', String, 'use the provided '\
|
284
|
+
'string as a version constraint for bundler' do |version|
|
285
|
+
@config['bundler_version'] = version
|
286
|
+
end
|
246
287
|
opt.on '--version=VERSION_CONSTRAINT', String, 'use the provided '\
|
247
288
|
'string as a version constraint for autoproj' do |version|
|
248
289
|
if @gemfile
|
@@ -257,9 +298,14 @@ module Autoproj
|
|
257
298
|
end
|
258
299
|
@gemfile = File.read(path)
|
259
300
|
end
|
301
|
+
opt.on '--no-seed-config',
|
302
|
+
'when reinstalling an existing autoproj workspace, do not '\
|
303
|
+
'use the config in .autoproj/ as seed' do
|
304
|
+
@config.clear
|
305
|
+
end
|
260
306
|
opt.on '--seed-config=PATH', String, 'path to a seed file that '\
|
261
307
|
'should be used to initialize the configuration' do |path|
|
262
|
-
|
308
|
+
add_seed_config(path)
|
263
309
|
end
|
264
310
|
opt.on '--prefer-os-independent-packages', 'prefer OS-independent '\
|
265
311
|
'packages (such as a RubyGem) over their OS-packaged equivalent '\
|
@@ -289,22 +335,50 @@ module Autoproj
|
|
289
335
|
@autoproj_options + args
|
290
336
|
end
|
291
337
|
|
292
|
-
def
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
return unless $?.success?
|
338
|
+
def bundler_version
|
339
|
+
@config['bundler_version']
|
340
|
+
end
|
341
|
+
|
342
|
+
def find_bundler(gem_program, version: nil)
|
298
343
|
bundler_path = File.join(gems_gem_home, 'bin', 'bundle')
|
299
|
-
|
300
|
-
|
301
|
-
|
344
|
+
return unless File.exist?(bundler_path)
|
345
|
+
|
346
|
+
setup_paths =
|
347
|
+
if version
|
348
|
+
find_versioned_bundler_setup(gem_program, version)
|
349
|
+
else
|
350
|
+
find_unversioned_bundler_setup(gem_program)
|
302
351
|
end
|
352
|
+
|
353
|
+
setup_paths.each do |setup_path|
|
354
|
+
return bundler_path if setup_path.start_with?(gems_gem_home)
|
303
355
|
end
|
304
|
-
|
356
|
+
nil
|
357
|
+
end
|
358
|
+
|
359
|
+
def find_versioned_bundler_setup(gem_program, version)
|
360
|
+
contents = IO.popen(
|
361
|
+
[env_for_child, Gem.ruby, gem_program,
|
362
|
+
'contents', '-v', version, 'bundler'],
|
363
|
+
&:readlines
|
364
|
+
)
|
365
|
+
return [] unless $CHILD_STATUS.success?
|
366
|
+
|
367
|
+
contents.grep(%r{bundler/setup.rb$})
|
368
|
+
end
|
369
|
+
|
370
|
+
def find_unversioned_bundler_setup(gem_program)
|
371
|
+
setup_paths = IO.popen(
|
372
|
+
[env_for_child, Gem.ruby, gem_program,
|
373
|
+
'which', '-a', 'bundler/setup'],
|
374
|
+
&:readlines
|
375
|
+
)
|
376
|
+
return [] unless $CHILD_STATUS.success?
|
377
|
+
|
378
|
+
setup_paths
|
305
379
|
end
|
306
380
|
|
307
|
-
def install_bundler(gem_program, silent: false)
|
381
|
+
def install_bundler(gem_program, version: nil, silent: false)
|
308
382
|
local = ['--local'] if local?
|
309
383
|
|
310
384
|
redirection = Hash.new
|
@@ -312,6 +386,9 @@ module Autoproj
|
|
312
386
|
redirection = Hash[out: :close]
|
313
387
|
end
|
314
388
|
|
389
|
+
version_args = []
|
390
|
+
version_args << '-v' << version if version
|
391
|
+
|
315
392
|
# Shut up the bundler warning about 'bin' not being in PATH
|
316
393
|
env = self.env
|
317
394
|
env['PATH'] += [File.join(gems_gem_home, 'bin')]
|
@@ -322,14 +399,14 @@ module Autoproj
|
|
322
399
|
'--clear-sources', '--source', gem_source,
|
323
400
|
'--no-user-install', '--install-dir', gems_gem_home,
|
324
401
|
*local, "--bindir=#{File.join(gems_gem_home, 'bin')}",
|
325
|
-
'bundler', **redirection)
|
402
|
+
'bundler', *version_args, **redirection)
|
326
403
|
|
327
404
|
if !result
|
328
405
|
STDERR.puts "FATAL: failed to install bundler in #{gems_gem_home}"
|
329
406
|
nil
|
330
407
|
end
|
331
408
|
|
332
|
-
if (bundler_path = find_bundler(gem_program))
|
409
|
+
if (bundler_path = find_bundler(gem_program, version: version))
|
333
410
|
bundler_path
|
334
411
|
else
|
335
412
|
STDERR.puts "gem install bundler returned successfully, but still "\
|
@@ -338,7 +415,7 @@ module Autoproj
|
|
338
415
|
end
|
339
416
|
end
|
340
417
|
|
341
|
-
def install_autoproj(bundler)
|
418
|
+
def install_autoproj(bundler, bundler_version: self.bundler_version)
|
342
419
|
# Force bundler to update. If the user does not want this, let
|
343
420
|
# him specify a Gemfile with tighter version constraints
|
344
421
|
lockfile = File.join(dot_autoproj, 'Gemfile.lock')
|
@@ -353,14 +430,19 @@ module Autoproj
|
|
353
430
|
opts << "--path=#{gems_install_path}"
|
354
431
|
shims_path = File.join(dot_autoproj, 'bin')
|
355
432
|
|
356
|
-
|
357
|
-
|
358
|
-
"--gemfile=#{autoproj_gemfile_path}",
|
359
|
-
"--shebang=#{Gem.ruby}",
|
360
|
-
"--binstubs=#{shims_path}",
|
361
|
-
*opts, chdir: dot_autoproj)
|
433
|
+
version_arg = []
|
434
|
+
version_arg << "_#{bundler_version}_" if bundler_version
|
362
435
|
|
363
|
-
|
436
|
+
result = system(
|
437
|
+
clean_env,
|
438
|
+
Gem.ruby, bundler, *version_arg, 'install',
|
439
|
+
"--gemfile=#{autoproj_gemfile_path}",
|
440
|
+
"--shebang=#{Gem.ruby}",
|
441
|
+
"--binstubs=#{shims_path}",
|
442
|
+
*opts, chdir: dot_autoproj
|
443
|
+
)
|
444
|
+
|
445
|
+
unless result
|
364
446
|
STDERR.puts "FATAL: failed to install autoproj in #{dot_autoproj}"
|
365
447
|
exit 1
|
366
448
|
end
|
@@ -369,7 +451,7 @@ module Autoproj
|
|
369
451
|
root_dir, autoproj_gemfile_path, gems_gem_home)
|
370
452
|
end
|
371
453
|
|
372
|
-
EXCLUDED_FROM_SHIMS = %w
|
454
|
+
EXCLUDED_FROM_SHIMS = %w[rake thor].freeze
|
373
455
|
|
374
456
|
def self.rewrite_shims(shim_path, ruby_executable,
|
375
457
|
root_dir, autoproj_gemfile_path, gems_gem_home)
|
@@ -425,11 +507,7 @@ module Autoproj
|
|
425
507
|
#
|
426
508
|
|
427
509
|
# Autoproj generated preamble
|
428
|
-
|
429
|
-
Bundler.with_clean_env do
|
430
|
-
exec($0, *ARGV)
|
431
|
-
end
|
432
|
-
end
|
510
|
+
#{WITHOUT_BUNDLER}
|
433
511
|
ENV['BUNDLE_GEMFILE'] ||= '#{autoproj_gemfile_path}'
|
434
512
|
ENV['GEM_HOME'] = '#{gems_gem_home}'
|
435
513
|
ENV.delete('GEM_PATH')
|
@@ -441,12 +519,7 @@ Gem.paths = Hash['GEM_HOME' => '#{gems_gem_home}', 'GEM_PATH' => '']
|
|
441
519
|
def self.shim_bundler_old(ruby_executable, autoproj_gemfile_path, gems_gem_home)
|
442
520
|
"#! #{ruby_executable}
|
443
521
|
|
444
|
-
|
445
|
-
Bundler.with_clean_env do
|
446
|
-
exec($0, *ARGV)
|
447
|
-
end
|
448
|
-
end
|
449
|
-
|
522
|
+
#{WITHOUT_BUNDLER}
|
450
523
|
ENV['BUNDLE_GEMFILE'] ||= '#{autoproj_gemfile_path}'
|
451
524
|
ENV['GEM_HOME'] = '#{gems_gem_home}'
|
452
525
|
ENV.delete('GEM_PATH')
|
@@ -471,14 +544,7 @@ load Gem.bin_path('bundler', 'bundler')"
|
|
471
544
|
#
|
472
545
|
|
473
546
|
# Autoproj generated preamble, v1
|
474
|
-
|
475
|
-
Bundler.with_clean_env do
|
476
|
-
exec(Hash['RUBYLIB' => nil], $0, *ARGV)
|
477
|
-
end
|
478
|
-
elsif ENV['RUBYLIB']
|
479
|
-
exec(Hash['RUBYLIB' => nil], $0, *ARGV)
|
480
|
-
end
|
481
|
-
|
547
|
+
#{RUBYLIB_REINIT}
|
482
548
|
ENV['BUNDLE_GEMFILE'] = '#{autoproj_gemfile_path}'
|
483
549
|
ENV['AUTOPROJ_CURRENT_ROOT'] = '#{root_dir}'
|
484
550
|
Gem.paths = Hash['GEM_HOME' => '#{gems_gem_home}', 'GEM_PATH' => '']
|
@@ -490,14 +556,7 @@ Gem.paths = Hash['GEM_HOME' => '#{gems_gem_home}', 'GEM_PATH' => '']
|
|
490
556
|
gems_gem_home, load_line)
|
491
557
|
"#! #{ruby_executable}
|
492
558
|
|
493
|
-
|
494
|
-
Bundler.with_clean_env do
|
495
|
-
exec(Hash['RUBYLIB' => nil], $0, *ARGV)
|
496
|
-
end
|
497
|
-
elsif ENV['RUBYLIB']
|
498
|
-
exec(Hash['RUBYLIB' => nil], $0, *ARGV)
|
499
|
-
end
|
500
|
-
|
559
|
+
#{RUBYLIB_REINIT}
|
501
560
|
ENV['BUNDLE_GEMFILE'] = '#{autoproj_gemfile_path}'
|
502
561
|
ENV['AUTOPROJ_CURRENT_ROOT'] = '#{root_dir}'
|
503
562
|
require 'rubygems'
|
@@ -591,8 +650,11 @@ require 'bundler/setup'
|
|
591
650
|
#
|
592
651
|
# So, we're calling 'gem' as a subcommand to discovery the
|
593
652
|
# actual bindir
|
594
|
-
bindir = IO.popen(
|
595
|
-
|
653
|
+
bindir = IO.popen(
|
654
|
+
env_for_child,
|
655
|
+
[Gem.ruby, '-e', 'puts "#{Gem.user_dir}/bin"'], # rubocop:disable Lint/InterpolationCheck
|
656
|
+
&:read
|
657
|
+
)
|
596
658
|
if bindir
|
597
659
|
@gem_bindir = bindir.chomp
|
598
660
|
else
|
@@ -600,11 +662,11 @@ require 'bundler/setup'
|
|
600
662
|
end
|
601
663
|
end
|
602
664
|
|
603
|
-
def install
|
665
|
+
def install(bundler_version: self.bundler_version)
|
604
666
|
if ENV['BUNDLER_GEMFILE']
|
605
667
|
raise "cannot run autoproj_install or autoproj_bootstrap while "\
|
606
|
-
|
607
|
-
|
668
|
+
"under a 'bundler exec' subcommand or having loaded an "\
|
669
|
+
"env.sh. Open a new console and try again"
|
608
670
|
end
|
609
671
|
|
610
672
|
gem_program = self.class.guess_gem_program
|
@@ -612,13 +674,12 @@ require 'bundler/setup'
|
|
612
674
|
env['GEM_HOME'] = [gems_gem_home]
|
613
675
|
env['GEM_PATH'] = [gems_gem_home]
|
614
676
|
|
615
|
-
if bundler = find_bundler(gem_program)
|
677
|
+
if (bundler = find_bundler(gem_program, version: bundler_version))
|
616
678
|
puts "Detected bundler at #{bundler}"
|
617
679
|
else
|
618
680
|
puts "Installing bundler in #{gems_gem_home}"
|
619
|
-
|
620
|
-
|
621
|
-
end
|
681
|
+
bundler = install_bundler(gem_program, version: bundler_version)
|
682
|
+
exit(1) unless bundler
|
622
683
|
end
|
623
684
|
self.class.rewrite_shims(
|
624
685
|
File.join(dot_autoproj, 'bin'),
|
@@ -630,7 +691,7 @@ require 'bundler/setup'
|
|
630
691
|
save_gemfile
|
631
692
|
|
632
693
|
puts "Installing autoproj in #{gems_gem_home}"
|
633
|
-
install_autoproj(bundler)
|
694
|
+
install_autoproj(bundler, bundler_version: bundler_version)
|
634
695
|
end
|
635
696
|
|
636
697
|
def load_config
|