autoproj 2.11.0 → 2.12.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/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.rb +1 -0
- data/lib/autoproj/autobuild_extensions/dsl.rb +4 -2
- data/lib/autoproj/base.rb +18 -0
- data/lib/autoproj/cli/cache.rb +35 -6
- data/lib/autoproj/cli/main.rb +28 -7
- data/lib/autoproj/cli/test.rb +1 -1
- data/lib/autoproj/cli/utility.rb +21 -25
- data/lib/autoproj/configuration.rb +12 -1
- data/lib/autoproj/installation_manifest.rb +7 -5
- data/lib/autoproj/ops/build.rb +23 -21
- data/lib/autoproj/ops/cache.rb +135 -30
- 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/os_package_installer.rb +19 -11
- data/lib/autoproj/package_managers/apt_dpkg_manager.rb +11 -5
- data/lib/autoproj/package_managers/bundler_manager.rb +100 -19
- data/lib/autoproj/package_managers/homebrew_manager.rb +2 -2
- data/lib/autoproj/test.rb +20 -6
- data/lib/autoproj/version.rb +1 -1
- data/lib/autoproj/workspace.rb +19 -4
- metadata +3 -2
data/bin/autoproj_install.in
CHANGED
@@ -13,8 +13,13 @@ require 'autoproj/ops/install'
|
|
13
13
|
ENV.delete('BUNDLE_GEMFILE')
|
14
14
|
ENV.delete('RUBYLIB')
|
15
15
|
ops = Autoproj::Ops::Install.new(Dir.pwd)
|
16
|
+
|
17
|
+
existing_config = File.join(Dir.pwd, '.autoproj', 'config.yml')
|
18
|
+
if File.file?(existing_config)
|
19
|
+
puts "Found existing configuration, using it as seed"
|
20
|
+
puts "use --no-seed-config to avoid this behavior"
|
21
|
+
ops.add_seed_config(existing_config)
|
22
|
+
end
|
16
23
|
ops.parse_options(ARGV)
|
17
24
|
ops.stage1
|
18
|
-
|
19
|
-
ops.call_stage2
|
20
|
-
end
|
25
|
+
ops.call_stage2 unless ops.skip_stage2?
|
data/lib/autoproj.rb
CHANGED
@@ -149,11 +149,13 @@ def ignore(*paths)
|
|
149
149
|
|
150
150
|
# Adds a new setup block to an existing package
|
151
151
|
def setup_package(package_name, workspace: Autoproj.workspace, &block)
|
152
|
-
|
152
|
+
unless block
|
153
|
+
raise Autoproj::ConfigError.new, 'you must give a block to #setup_package'
|
154
|
+
end
|
153
155
|
|
154
156
|
package_definition = workspace.manifest.find_package_definition(package_name)
|
155
157
|
if !package_definition
|
156
|
-
raise ConfigError.new, "#{package_name} is not a known package"
|
158
|
+
raise Autoproj::ConfigError.new, "#{package_name} is not a known package"
|
157
159
|
elsif package_definition.autobuild.kind_of?(Autobuild::DummyPackage)
|
158
160
|
# Nothing to do!
|
159
161
|
else
|
data/lib/autoproj/base.rb
CHANGED
@@ -56,4 +56,22 @@ def self.post_import(*packages, &block)
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
59
|
+
|
60
|
+
# Shim for a smooth upgrade path to bundler 2.1+
|
61
|
+
def self.bundler_unbundled_system(*args, **options)
|
62
|
+
if Bundler.respond_to?(:unbundled_system)
|
63
|
+
Bundler.unbundled_system(*args, **options)
|
64
|
+
else
|
65
|
+
Bundler.clean_system(*args, **options)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Shim for a smooth upgrade path to bundler 2.1+
|
70
|
+
def self.bundler_with_unbundled_env(&block)
|
71
|
+
if Bundler.respond_to?(:with_unbundled_env)
|
72
|
+
Bundler.with_unbundled_env(&block)
|
73
|
+
else
|
74
|
+
Bundler.with_clean_env(&block)
|
75
|
+
end
|
76
|
+
end
|
59
77
|
end
|
data/lib/autoproj/cli/cache.rb
CHANGED
@@ -10,21 +10,50 @@ def validate_options(argv, options = Hash.new)
|
|
10
10
|
if argv.empty?
|
11
11
|
default_cache_dirs = Autobuild::Importer.default_cache_dirs
|
12
12
|
if !default_cache_dirs || default_cache_dirs.empty?
|
13
|
-
raise CLIInvalidArguments,
|
13
|
+
raise CLIInvalidArguments,
|
14
|
+
"no cache directory defined with e.g. the "\
|
15
|
+
"AUTOBUILD_CACHE_DIR environment variable, "\
|
16
|
+
"expected one cache directory as argument"
|
14
17
|
end
|
15
|
-
Autoproj.warn "using cache directory #{default_cache_dirs.first}
|
18
|
+
Autoproj.warn "using cache directory #{default_cache_dirs.first} "\
|
19
|
+
"from the autoproj configuration"
|
16
20
|
argv << default_cache_dirs.first
|
17
21
|
end
|
18
22
|
|
19
|
-
|
23
|
+
if (compile = options[:gems_compile])
|
24
|
+
options[:gems_compile] = compile.map do |name|
|
25
|
+
name, *artifacts = name.split('+')
|
26
|
+
[name, artifacts: artifacts]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
[File.expand_path(argv.first, ws.root_dir), *argv[1..-1], options]
|
20
31
|
end
|
21
32
|
|
22
|
-
def run(cache_dir, *package_names,
|
33
|
+
def run(cache_dir, *package_names,
|
34
|
+
keep_going: false,
|
35
|
+
packages: true, all: true, checkout_only: false,
|
36
|
+
gems: false, gems_compile: [], gems_compile_force: false)
|
23
37
|
initialize_and_load
|
24
38
|
finalize_setup
|
25
39
|
|
26
|
-
cache_op = Autoproj::Ops::Cache.new(cache_dir, ws
|
27
|
-
|
40
|
+
cache_op = Autoproj::Ops::Cache.new(cache_dir, ws)
|
41
|
+
if packages
|
42
|
+
cache_op.create_or_update(
|
43
|
+
*package_names,
|
44
|
+
all: all, keep_going: keep_going,
|
45
|
+
checkout_only: checkout_only
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
if gems
|
50
|
+
Autoproj.message "caching gems in #{cache_op.gems_cache_dir}"
|
51
|
+
cache_op.create_or_update_gems(
|
52
|
+
keep_going: keep_going,
|
53
|
+
compile: gems_compile,
|
54
|
+
compile_force: gems_compile_force
|
55
|
+
)
|
56
|
+
end
|
28
57
|
end
|
29
58
|
end
|
30
59
|
end
|
data/lib/autoproj/cli/main.rb
CHANGED
@@ -300,13 +300,34 @@ def build(*packages)
|
|
300
300
|
end
|
301
301
|
end
|
302
302
|
|
303
|
-
desc 'cache CACHE_DIR', 'create or update a cache directory that
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
option :
|
309
|
-
|
303
|
+
desc 'cache CACHE_DIR', 'create or update a cache directory that '\
|
304
|
+
'can be given to AUTOBUILD_CACHE_DIR'
|
305
|
+
option :keep_going,
|
306
|
+
aliases: :k,
|
307
|
+
desc: 'do not stop on errors'
|
308
|
+
option :checkout_only,
|
309
|
+
aliases: :c, type: :boolean, default: false,
|
310
|
+
desc: 'only checkout packages, do not update already-cached ones'
|
311
|
+
option :all,
|
312
|
+
type: :boolean, default: true,
|
313
|
+
desc: 'cache all defined packages (the default), '\
|
314
|
+
' or only the selected ones'
|
315
|
+
option :packages,
|
316
|
+
type: :boolean, default: true,
|
317
|
+
desc: 'update the package cache'
|
318
|
+
option :gems,
|
319
|
+
type: :boolean, default: false,
|
320
|
+
desc: 'update the gems cache'
|
321
|
+
option :gems_compile_force,
|
322
|
+
type: :boolean, default: false,
|
323
|
+
desc: 'with --gems-compile, recompile existing gems as well'
|
324
|
+
option :gems_compile,
|
325
|
+
type: :array,
|
326
|
+
desc: 'pre-compile the following gems. This requires gem-compiler '\
|
327
|
+
'to be available in the workspace. Use GEM_NAME+ARTIFACT'\
|
328
|
+
'[+ARTIFACT] to add files or directories to the precompiled '\
|
329
|
+
'gems beyond what gem-compiler auto-adds (which is mostly '\
|
330
|
+
'dynamic libraries)'
|
310
331
|
def cache(*args)
|
311
332
|
run_autoproj_cli(:cache, :Cache, Hash[], *args)
|
312
333
|
end
|
data/lib/autoproj/cli/test.rb
CHANGED
@@ -10,7 +10,7 @@ def initialize(ws = Workspace.default,
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def package_metadata(package)
|
13
|
-
u = package.
|
13
|
+
u = package.test_utility
|
14
14
|
super.merge(
|
15
15
|
'coverage_available' => !!u.coverage_available?,
|
16
16
|
'coverage_enabled' => !!u.coverage_enabled?,
|
data/lib/autoproj/cli/utility.rb
CHANGED
@@ -89,24 +89,37 @@ def run(user_selection, options = {})
|
|
89
89
|
raise CLIInvalidArguments, "autoproj: the provided package "\
|
90
90
|
"is not selected for build"
|
91
91
|
end
|
92
|
+
return if package_names.empty?
|
92
93
|
|
93
94
|
packages = package_names.map do |pkg_name|
|
94
95
|
ws.manifest.find_package_definition(pkg_name)
|
95
96
|
end
|
96
97
|
|
98
|
+
apply_to_packages(packages, parallel: options[:parallel])
|
99
|
+
end
|
100
|
+
|
101
|
+
def apply_to_packages(packages, parallel: ws.config.parallel_build_level)
|
102
|
+
if @report_path
|
103
|
+
reporting = Ops::PhaseReporting.new(
|
104
|
+
@utility_name, @report_path,
|
105
|
+
method(:package_metadata)
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
reporting&.initialize_incremental_report
|
97
110
|
Autobuild.apply(
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
111
|
+
packages.map(&:name), "autoproj-#{@utility_name}",
|
112
|
+
[@utility_name], parallel: parallel
|
113
|
+
) do |pkg, phase|
|
114
|
+
reporting&.report_incremental(pkg) if phase == utility_name
|
115
|
+
end
|
103
116
|
|
104
117
|
ensure
|
105
|
-
create_report(packages)
|
118
|
+
reporting&.create_report(packages.map(&:autobuild))
|
106
119
|
end
|
107
120
|
|
108
|
-
def package_metadata(
|
109
|
-
u =
|
121
|
+
def package_metadata(autobuild_package)
|
122
|
+
u = autobuild_package.utility(@utility_name)
|
110
123
|
{
|
111
124
|
'source_dir' => u.source_dir,
|
112
125
|
'target_dir' => u.target_dir,
|
@@ -117,23 +130,6 @@ def package_metadata(package)
|
|
117
130
|
'installed' => !!u.installed?,
|
118
131
|
}
|
119
132
|
end
|
120
|
-
|
121
|
-
def create_report(packages)
|
122
|
-
info = packages.each_with_object({}) do |p, map|
|
123
|
-
map[p.name] = package_metadata(p)
|
124
|
-
end
|
125
|
-
|
126
|
-
FileUtils.mkdir_p File.dirname(@report_path)
|
127
|
-
File.open(@report_path, 'w') do |io|
|
128
|
-
dump = JSON.dump(
|
129
|
-
"#{@utility_name}_report" => {
|
130
|
-
'timestamp' => Time.now,
|
131
|
-
'packages' => info
|
132
|
-
}
|
133
|
-
)
|
134
|
-
io.write dump
|
135
|
-
end
|
136
|
-
end
|
137
133
|
end
|
138
134
|
end
|
139
135
|
end
|
@@ -196,7 +196,9 @@ def configure(option_name)
|
|
196
196
|
Autoproj.info " using: #{value} (noninteractive mode)"
|
197
197
|
end
|
198
198
|
@modified = true
|
199
|
-
if
|
199
|
+
if is_default
|
200
|
+
value = opt.validate(value)
|
201
|
+
else
|
200
202
|
config[option_name] = [value, true]
|
201
203
|
displayed_options[option_name] = value
|
202
204
|
end
|
@@ -353,6 +355,10 @@ def shell_helpers=(flag)
|
|
353
355
|
set 'shell_helpers', flag, true
|
354
356
|
end
|
355
357
|
|
358
|
+
def bundler_version
|
359
|
+
get 'bundler_version', nil
|
360
|
+
end
|
361
|
+
|
356
362
|
def apply_autobuild_configuration
|
357
363
|
if has_value_for?('autobuild')
|
358
364
|
params = get('autobuild')
|
@@ -369,6 +375,11 @@ def importer_cache_dir
|
|
369
375
|
get('importer_cache_dir', nil)
|
370
376
|
end
|
371
377
|
|
378
|
+
# Set import and gem cache directory
|
379
|
+
def importer_cache_dir=(path)
|
380
|
+
set('importer_cache_dir', path, true)
|
381
|
+
end
|
382
|
+
|
372
383
|
# Sets the directory in which packages will be installed
|
373
384
|
def prefix_dir=(path)
|
374
385
|
set('prefix', path, true)
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Autoproj
|
2
2
|
# Manifest of installed packages imported from another autoproj installation
|
3
3
|
class InstallationManifest
|
4
|
-
Package = Struct.new :name, :type, :vcs, :srcdir, :
|
4
|
+
Package = Struct.new :name, :type, :vcs, :srcdir, :importdir,
|
5
|
+
:prefix, :builddir, :logdir, :dependencies
|
5
6
|
PackageSet = Struct.new :name, :vcs, :raw_local_dir, :user_local_dir
|
6
7
|
|
7
8
|
attr_reader :path
|
@@ -28,11 +29,11 @@ def add_package_set(pkg_set)
|
|
28
29
|
def each_package_set(&block)
|
29
30
|
package_sets.each_value(&block)
|
30
31
|
end
|
31
|
-
|
32
|
+
|
32
33
|
def each_package(&block)
|
33
34
|
packages.each_value(&block)
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
def load
|
37
38
|
@packages = Hash.new
|
38
39
|
raw = YAML.load(File.open(path))
|
@@ -51,8 +52,8 @@ def load
|
|
51
52
|
package_sets[pkg_set.name] = pkg_set
|
52
53
|
else
|
53
54
|
pkg = Package.new(
|
54
|
-
entry['name'], entry['type'], entry['vcs'], entry['srcdir'], entry['
|
55
|
-
entry['builddir'], entry['logdir'], entry['dependencies'])
|
55
|
+
entry['name'], entry['type'], entry['vcs'], entry['srcdir'], entry['importdir'],
|
56
|
+
entry['prefix'], entry['builddir'], entry['logdir'], entry['dependencies'])
|
56
57
|
packages[pkg.name] = pkg
|
57
58
|
end
|
58
59
|
end
|
@@ -74,6 +75,7 @@ def save(path = self.path)
|
|
74
75
|
'type' => v.class.name,
|
75
76
|
'vcs' => package_def.vcs.to_hash,
|
76
77
|
'srcdir' => v.srcdir,
|
78
|
+
'importdir' => (v.importdir if v.respond_to?(:importdir)),
|
77
79
|
'builddir' => (v.builddir if v.respond_to?(:builddir)),
|
78
80
|
'logdir' => v.logdir,
|
79
81
|
'prefix' => v.prefix,
|
data/lib/autoproj/ops/build.rb
CHANGED
@@ -87,34 +87,36 @@ def force_build_packages(selected_packages, all_enabled_packages)
|
|
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 @@ class Cache
|
|
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 @@ def git_cache_dir
|
|
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 @@ def cache_archive(pkg)
|
|
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 @@ def create_or_update(*package_names, all: true, keep_going: false, checkout_only
|
|
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,7 +100,10 @@ def create_or_update(*package_names, all: true, keep_going: false, checkout_only
|
|
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
|
@@ -103,27 +118,117 @@ def create_or_update(*package_names, all: true, keep_going: false, checkout_only
|
|
103
118
|
rescue Interrupt
|
104
119
|
raise
|
105
120
|
rescue ::Exception => e
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
pkg.message(
|
116
|
-
|
117
|
-
|
121
|
+
raise unless keep_going
|
122
|
+
|
123
|
+
pkg.error " failed to cache #{pkg.name}, "\
|
124
|
+
'but going on as requested'
|
125
|
+
lines = e.to_s.split('\n')
|
126
|
+
lines = e.message.split('\n') if lines.empty?
|
127
|
+
lines = ['unknown error'] if lines.empty?
|
128
|
+
pkg.message(lines.shift, :red, :bold)
|
129
|
+
lines.each do |line|
|
130
|
+
pkg.message(line)
|
131
|
+
end
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def gems_cache_dir
|
138
|
+
File.join(cache_dir, 'package_managers', 'gem')
|
139
|
+
end
|
140
|
+
|
141
|
+
def create_or_update_gems(keep_going: true, compile_force: false, compile: [])
|
142
|
+
# Note: this might directly copy into the cache directoy, and
|
143
|
+
# we support it later
|
144
|
+
cache_dir = File.join(@ws.prefix_dir, 'gems', 'vendor', 'cache')
|
145
|
+
PackageManagers::BundlerManager.run_bundler(
|
146
|
+
@ws, 'cache'
|
147
|
+
)
|
148
|
+
|
149
|
+
FileUtils.mkdir_p(gems_cache_dir) unless File.exist?(gems_cache_dir)
|
150
|
+
|
151
|
+
needs_copy =
|
152
|
+
if File.exist?(cache_dir)
|
153
|
+
real_cache_dir = File.realpath(cache_dir)
|
154
|
+
real_target_dir = File.realpath(gems_cache_dir)
|
155
|
+
(real_cache_dir != real_target_dir)
|
156
|
+
end
|
157
|
+
|
158
|
+
synchronize_gems_cache_dirs(real_cache_dir, real_target_dir) if needs_copy
|
159
|
+
|
160
|
+
platform_suffix = "-#{Gem::Platform.local}.gem"
|
161
|
+
failed = []
|
162
|
+
compile.each do |gem_name, artifacts: []|
|
163
|
+
Dir.glob(File.join(cache_dir, "#{gem_name}*.gem")) do |gem|
|
164
|
+
next if gem.end_with?(platform_suffix)
|
165
|
+
|
166
|
+
gem_basename = File.basename(gem, ".gem")
|
167
|
+
expected_platform_gem = File.join(
|
168
|
+
real_target_dir, "#{gem_basename}#{platform_suffix}"
|
169
|
+
)
|
170
|
+
next if !compile_force && File.file?(expected_platform_gem)
|
171
|
+
|
172
|
+
begin
|
173
|
+
compile_gem(gem, artifacts: artifacts, output: real_target_dir)
|
174
|
+
rescue CompilationFailed
|
175
|
+
unless keep_going
|
176
|
+
raise CompilationFailed, "#{gem} failed to compile"
|
118
177
|
end
|
119
|
-
|
120
|
-
|
121
|
-
raise
|
178
|
+
|
179
|
+
failed << gem
|
122
180
|
end
|
123
181
|
end
|
124
182
|
end
|
183
|
+
|
184
|
+
unless failed.empty?
|
185
|
+
raise CompilationFailed, "#{failed.sort.join(', ')} failed to compile"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
class CompilationFailed < RuntimeError; end
|
190
|
+
|
191
|
+
def synchronize_gems_cache_dirs(source, target)
|
192
|
+
Dir.glob(File.join(source, "*.gem")) do |source_file|
|
193
|
+
basename = File.basename(source_file)
|
194
|
+
target_file = File.join(target, basename)
|
195
|
+
next if File.file?(target_file)
|
196
|
+
|
197
|
+
Autoproj.message "gems: caching #{basename}"
|
198
|
+
FileUtils.cp source_file, target_file
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def guess_gem_program
|
203
|
+
if Autobuild.programs['gem']
|
204
|
+
return Autobuild.programs['gem']
|
205
|
+
end
|
206
|
+
|
207
|
+
ruby_bin = RbConfig::CONFIG['RUBY_INSTALL_NAME']
|
208
|
+
ruby_bindir = RbConfig::CONFIG['bindir']
|
209
|
+
|
210
|
+
candidates = ['gem']
|
211
|
+
if ruby_bin =~ /^ruby(.+)$/
|
212
|
+
candidates << "gem#{$1}"
|
213
|
+
end
|
214
|
+
|
215
|
+
candidates.each do |gem_name|
|
216
|
+
if File.file?(gem_full_path = File.join(ruby_bindir, gem_name))
|
217
|
+
Autobuild.programs['gem'] = gem_full_path
|
218
|
+
return Autobuild.programs['gem']
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
raise ArgumentError, "cannot find a gem program (tried #{candidates.sort.join(", ")} in #{ruby_bindir})"
|
223
|
+
end
|
224
|
+
|
225
|
+
private def compile_gem(gem_path, output:, artifacts: [])
|
226
|
+
artifacts = artifacts.flat_map { |n| ["--artifact", n] }
|
227
|
+
unless system(Autobuild.tool('ruby'), '-S', guess_gem_program,
|
228
|
+
'compile', '--output', output, *artifacts, gem_path)
|
229
|
+
raise CompilationFailed, "#{gem_path} failed to compile"
|
230
|
+
end
|
125
231
|
end
|
126
232
|
end
|
127
233
|
end
|
128
234
|
end
|
129
|
-
|