autoproj 2.13.0 → 2.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/lint.yml +25 -0
  3. data/.github/workflows/test.yml +30 -0
  4. data/.rubocop.yml +79 -91
  5. data/.rubocop_todo.yml +1473 -0
  6. data/Gemfile +9 -9
  7. data/Rakefile +24 -24
  8. data/autoproj.gemspec +24 -22
  9. data/bin/alocate +4 -4
  10. data/bin/alog +5 -7
  11. data/bin/amake +4 -4
  12. data/bin/aup +4 -4
  13. data/bin/autoproj +3 -3
  14. data/bin/autoproj_bootstrap +224 -199
  15. data/bin/autoproj_bootstrap.in +7 -8
  16. data/bin/autoproj_install +223 -198
  17. data/bin/autoproj_install.in +6 -7
  18. data/lib/autoproj/aruba_minitest.rb +6 -11
  19. data/lib/autoproj/autobuild.rb +9 -6
  20. data/lib/autoproj/autobuild_extensions/archive_importer.rb +10 -11
  21. data/lib/autoproj/autobuild_extensions/dsl.rb +64 -34
  22. data/lib/autoproj/autobuild_extensions/git.rb +27 -26
  23. data/lib/autoproj/autobuild_extensions/package.rb +23 -22
  24. data/lib/autoproj/autobuild_extensions/python.rb +18 -0
  25. data/lib/autoproj/autobuild_extensions/svn.rb +1 -2
  26. data/lib/autoproj/base.rb +1 -1
  27. data/lib/autoproj/bash_completion.rb +5 -6
  28. data/lib/autoproj/build_option.rb +22 -24
  29. data/lib/autoproj/cli/base.rb +26 -26
  30. data/lib/autoproj/cli/bootstrap.rb +14 -16
  31. data/lib/autoproj/cli/build.rb +10 -7
  32. data/lib/autoproj/cli/cache.rb +11 -11
  33. data/lib/autoproj/cli/clean.rb +10 -10
  34. data/lib/autoproj/cli/commit.rb +7 -8
  35. data/lib/autoproj/cli/doc.rb +2 -2
  36. data/lib/autoproj/cli/envsh.rb +1 -2
  37. data/lib/autoproj/cli/exec.rb +60 -20
  38. data/lib/autoproj/cli/inspection_tool.rb +13 -7
  39. data/lib/autoproj/cli/locate.rb +30 -41
  40. data/lib/autoproj/cli/log.rb +7 -7
  41. data/lib/autoproj/cli/main.rb +213 -204
  42. data/lib/autoproj/cli/main_doc.rb +22 -21
  43. data/lib/autoproj/cli/main_global.rb +44 -19
  44. data/lib/autoproj/cli/main_plugin.rb +18 -18
  45. data/lib/autoproj/cli/main_test.rb +28 -27
  46. data/lib/autoproj/cli/manifest.rb +7 -7
  47. data/lib/autoproj/cli/osdeps.rb +12 -11
  48. data/lib/autoproj/cli/patcher.rb +2 -3
  49. data/lib/autoproj/cli/query.rb +17 -18
  50. data/lib/autoproj/cli/reconfigure.rb +1 -2
  51. data/lib/autoproj/cli/reset.rb +9 -12
  52. data/lib/autoproj/cli/show.rb +38 -39
  53. data/lib/autoproj/cli/status.rb +45 -39
  54. data/lib/autoproj/cli/switch_config.rb +5 -6
  55. data/lib/autoproj/cli/tag.rb +12 -11
  56. data/lib/autoproj/cli/test.rb +7 -7
  57. data/lib/autoproj/cli/update.rb +35 -37
  58. data/lib/autoproj/cli/utility.rb +11 -10
  59. data/lib/autoproj/cli/version.rb +42 -40
  60. data/lib/autoproj/cli/versions.rb +14 -15
  61. data/lib/autoproj/cli/watch.rb +33 -37
  62. data/lib/autoproj/cli/which.rb +16 -20
  63. data/lib/autoproj/cli.rb +4 -2
  64. data/lib/autoproj/configuration.rb +77 -85
  65. data/lib/autoproj/default.osdeps +18 -3
  66. data/lib/autoproj/environment.rb +42 -23
  67. data/lib/autoproj/exceptions.rb +9 -3
  68. data/lib/autoproj/find_workspace.rb +20 -25
  69. data/lib/autoproj/git_server_configuration.rb +40 -44
  70. data/lib/autoproj/gitorious.rb +1 -1
  71. data/lib/autoproj/installation_manifest.rb +64 -29
  72. data/lib/autoproj/local_package_set.rb +13 -11
  73. data/lib/autoproj/manifest.rb +137 -130
  74. data/lib/autoproj/metapackage.rb +2 -6
  75. data/lib/autoproj/ops/atomic_write.rb +7 -6
  76. data/lib/autoproj/ops/build.rb +4 -6
  77. data/lib/autoproj/ops/cache.rb +41 -43
  78. data/lib/autoproj/ops/cached_env.rb +5 -4
  79. data/lib/autoproj/ops/configuration.rb +525 -507
  80. data/lib/autoproj/ops/import.rb +76 -64
  81. data/lib/autoproj/ops/install.rb +217 -191
  82. data/lib/autoproj/ops/loader.rb +77 -76
  83. data/lib/autoproj/ops/main_config_switcher.rb +36 -45
  84. data/lib/autoproj/ops/phase_reporting.rb +4 -4
  85. data/lib/autoproj/ops/snapshot.rb +250 -247
  86. data/lib/autoproj/ops/tools.rb +76 -78
  87. data/lib/autoproj/ops/watch.rb +6 -6
  88. data/lib/autoproj/ops/which.rb +17 -14
  89. data/lib/autoproj/options.rb +13 -2
  90. data/lib/autoproj/os_package_installer.rb +102 -92
  91. data/lib/autoproj/os_package_query.rb +7 -13
  92. data/lib/autoproj/os_package_resolver.rb +189 -140
  93. data/lib/autoproj/os_repository_installer.rb +4 -4
  94. data/lib/autoproj/os_repository_resolver.rb +8 -6
  95. data/lib/autoproj/package_definition.rb +12 -13
  96. data/lib/autoproj/package_managers/apt_dpkg_manager.rb +19 -11
  97. data/lib/autoproj/package_managers/bundler_manager.rb +186 -129
  98. data/lib/autoproj/package_managers/debian_version.rb +25 -21
  99. data/lib/autoproj/package_managers/emerge_manager.rb +2 -3
  100. data/lib/autoproj/package_managers/gem_manager.rb +68 -77
  101. data/lib/autoproj/package_managers/homebrew_manager.rb +3 -4
  102. data/lib/autoproj/package_managers/manager.rb +8 -3
  103. data/lib/autoproj/package_managers/pacman_manager.rb +2 -3
  104. data/lib/autoproj/package_managers/pip_manager.rb +30 -28
  105. data/lib/autoproj/package_managers/pkg_manager.rb +3 -4
  106. data/lib/autoproj/package_managers/port_manager.rb +2 -3
  107. data/lib/autoproj/package_managers/shell_script_manager.rb +47 -25
  108. data/lib/autoproj/package_managers/unknown_os_manager.rb +5 -8
  109. data/lib/autoproj/package_managers/yum_manager.rb +12 -15
  110. data/lib/autoproj/package_managers/zypper_manager.rb +11 -14
  111. data/lib/autoproj/package_manifest.rb +28 -74
  112. data/lib/autoproj/package_selection.rb +187 -187
  113. data/lib/autoproj/package_set.rb +144 -113
  114. data/lib/autoproj/python.rb +297 -0
  115. data/lib/autoproj/query_base.rb +20 -14
  116. data/lib/autoproj/reporter.rb +19 -19
  117. data/lib/autoproj/repository_managers/apt.rb +102 -68
  118. data/lib/autoproj/repository_managers/unknown_os_manager.rb +3 -3
  119. data/lib/autoproj/ros_condition_parser.rb +84 -0
  120. data/lib/autoproj/ros_package_manifest.rb +125 -0
  121. data/lib/autoproj/shell_completion.rb +16 -13
  122. data/lib/autoproj/source_package_query.rb +29 -36
  123. data/lib/autoproj/system.rb +32 -21
  124. data/lib/autoproj/test.rb +127 -104
  125. data/lib/autoproj/variable_expansion.rb +7 -9
  126. data/lib/autoproj/vcs_definition.rb +35 -32
  127. data/lib/autoproj/version.rb +1 -1
  128. data/lib/autoproj/workspace.rb +142 -108
  129. data/lib/autoproj/zsh_completion.rb +8 -9
  130. data/lib/autoproj.rb +55 -55
  131. data/samples/autoproj/init.rb +1 -2
  132. metadata +80 -46
  133. data/.travis.yml +0 -24
@@ -1,4 +1,4 @@
1
- require 'bundler'
1
+ require "bundler"
2
2
  module Autoproj
3
3
  module PackageManagers
4
4
  # Package manager interface for the RubyGems system
@@ -49,23 +49,23 @@ module Autoproj
49
49
 
50
50
  config = ws.config
51
51
 
52
- env.add_path 'PATH', File.join(ws.prefix_dir, 'gems', 'bin')
53
- env.add_path 'PATH', File.join(ws.dot_autoproj_dir, 'bin')
54
- env.set 'GEM_HOME', config.gems_gem_home
55
- env.clear 'GEM_PATH'
52
+ env.add_path "PATH", File.join(ws.prefix_dir, "gems", "bin")
53
+ env.add_path "PATH", File.join(ws.dot_autoproj_dir, "bin")
54
+ env.set "GEM_HOME", config.gems_gem_home
55
+ env.clear "GEM_PATH"
56
56
  if (bundler_version = config.bundler_version)
57
- env.set 'BUNDLER_VERSION', bundler_version
57
+ env.set "BUNDLER_VERSION", bundler_version
58
58
  else
59
- env.clear 'BUNDLER_VERSION'
59
+ env.clear "BUNDLER_VERSION"
60
60
  end
61
61
 
62
- gemfile_path = File.join(ws.prefix_dir, 'gems', 'Gemfile')
63
- env.set('BUNDLE_GEMFILE', gemfile_path) if File.file?(gemfile_path)
62
+ gemfile_path = File.join(ws.prefix_dir, "gems", "Gemfile")
63
+ env.set("BUNDLE_GEMFILE", gemfile_path) if File.file?(gemfile_path)
64
64
 
65
65
  if cache_dir && File.exist?(cache_dir)
66
- vendor_dir = File.join(File.dirname(gemfile_path), 'vendor')
66
+ vendor_dir = File.join(File.dirname(gemfile_path), "vendor")
67
67
  FileUtils.mkdir_p vendor_dir
68
- bundler_cache_dir = File.join(vendor_dir, 'cache')
68
+ bundler_cache_dir = File.join(vendor_dir, "cache")
69
69
  if File.writable?(cache_dir)
70
70
  create_cache_symlink(cache_dir, bundler_cache_dir)
71
71
  else
@@ -75,16 +75,16 @@ module Autoproj
75
75
  end
76
76
  end
77
77
 
78
- Autobuild.programs['bundler'] =
79
- Autobuild.programs['bundle'] =
80
- File.join(ws.dot_autoproj_dir, 'bin', 'bundle')
78
+ Autobuild.programs["bundler"] =
79
+ Autobuild.programs["bundle"] =
80
+ File.join(ws.dot_autoproj_dir, "bin", "bundle")
81
81
 
82
- env.init_from_env 'RUBYLIB'
83
- env.inherit 'RUBYLIB'
82
+ env.init_from_env "RUBYLIB"
83
+ env.inherit "RUBYLIB"
84
84
  # Sanitize the rubylib we get from the environment by removing
85
85
  # anything that comes from Gem or Bundler
86
86
  original_rubylib =
87
- (env['RUBYLIB'] || "").split(File::PATH_SEPARATOR).find_all do |p|
87
+ (env["RUBYLIB"] || "").split(File::PATH_SEPARATOR).find_all do |p|
88
88
  !p.start_with?(Bundler.rubygems.gem_dir) &&
89
89
  Bundler.rubygems.gem_path
90
90
  .none? { |gem_p| p.start_with?(gem_p) }
@@ -97,22 +97,22 @@ module Autoproj
97
97
  #
98
98
  # This allows to use a binstub generated for one of ruby
99
99
  # interpreter version on our workspace
100
- env.system_env['RUBYLIB'] = []
101
- env.original_env['RUBYLIB'] = (original_rubylib - system_rubylib)
100
+ env.system_env["RUBYLIB"] = []
101
+ env.original_env["RUBYLIB"] = (original_rubylib - system_rubylib)
102
102
  .join(File::PATH_SEPARATOR)
103
103
  end
104
104
 
105
105
  ws.config.each_reused_autoproj_installation do |p|
106
106
  reused_w = ws.new(p)
107
- env.add_path 'PATH', File.join(reused_w.prefix_dir, 'gems', 'bin')
107
+ env.add_path "PATH", File.join(reused_w.prefix_dir, "gems", "bin")
108
108
  end
109
109
 
110
110
  prefix_gems = File.join(ws.prefix_dir, "gems")
111
111
  FileUtils.mkdir_p prefix_gems
112
- gemfile = File.join(prefix_gems, 'Gemfile')
112
+ gemfile = File.join(prefix_gems, "Gemfile")
113
113
  unless File.exist?(gemfile)
114
114
  Ops.atomic_write(gemfile) do |io|
115
- dot_autoproj_gemfile = File.join(ws.dot_autoproj_dir, 'Gemfile')
115
+ dot_autoproj_gemfile = File.join(ws.dot_autoproj_dir, "Gemfile")
116
116
  io.puts "eval_gemfile \"#{dot_autoproj_gemfile}\""
117
117
  end
118
118
  end
@@ -123,13 +123,14 @@ module Autoproj
123
123
  end
124
124
 
125
125
  def create_cache_symlink(cache_dir, bundler_cache_dir)
126
- valid = !File.exist?(bundler_cache_dir) ||
127
- File.symlink?(bundler_cache_dir)
128
-
129
- unless valid
130
- Autoproj.warn "cannot use #{cache_dir} as gem cache as "\
131
- "#{bundler_cache_dir} already exists"
132
- return
126
+ if File.exist?(bundler_cache_dir)
127
+ if !File.symlink?(bundler_cache_dir)
128
+ Autoproj.warn "cannot use #{cache_dir} as gem cache as "\
129
+ "#{bundler_cache_dir} already exists"
130
+ return
131
+ elsif File.readlink(bundler_cache_dir) == cache_dir
132
+ return
133
+ end
133
134
  end
134
135
 
135
136
  FileUtils.rm_f bundler_cache_dir
@@ -151,7 +152,7 @@ module Autoproj
151
152
  FileUtils.rm_f bundler_cache_dir if File.symlink?(bundler_cache_dir)
152
153
  FileUtils.mkdir_p bundler_cache_dir
153
154
 
154
- Dir.glob(File.join(cache_dir, '*.gem')) do |path_src|
155
+ Dir.glob(File.join(cache_dir, "*.gem")) do |path_src|
155
156
  path_dest = File.join(bundler_cache_dir, File.basename(path_src))
156
157
  next if File.exist?(path_dest)
157
158
 
@@ -161,7 +162,7 @@ module Autoproj
161
162
 
162
163
  # Enumerate the per-gem build configurations
163
164
  def self.per_gem_build_config(ws)
164
- ws.config.get('bundler.build', {})
165
+ ws.config.get("bundler.build", {})
165
166
  end
166
167
 
167
168
  # Add new build configuration arguments for a given gem
@@ -169,9 +170,9 @@ module Autoproj
169
170
  # This is meant to be used from the Autoproj configuration files,
170
171
  # e.g. overrides.rb or package configuration
171
172
  def self.add_build_configuration_for(gem_name, build_config, ws: Autoproj.workspace)
172
- c = ws.config.get('bundler.build', {})
173
+ c = ws.config.get("bundler.build", {})
173
174
  c[gem_name] = [c[gem_name], build_config].compact.join(" ")
174
- ws.config.set('bundler.build', c)
175
+ ws.config.set("bundler.build", c)
175
176
  end
176
177
 
177
178
  # Set the build configuration for the given gem
@@ -179,9 +180,9 @@ module Autoproj
179
180
  # This is meant to be used from the Autoproj configuration files,
180
181
  # e.g. overrides.rb or package configuration
181
182
  def self.configure_build_for(gem_name, build_config, ws: Autoproj.workspace)
182
- c = ws.config.get('bundler.build', {})
183
+ c = ws.config.get("bundler.build", {})
183
184
  c[gem_name] = build_config
184
- ws.config.set('bundler.build', c)
185
+ ws.config.set("bundler.build", c)
185
186
  end
186
187
 
187
188
  # Removes build configuration flags for the given gem
@@ -189,9 +190,9 @@ module Autoproj
189
190
  # This is meant to be used from the Autoproj configuration files,
190
191
  # e.g. overrides.rb or package configuration
191
192
  def self.remove_build_configuration_for(gem_name, ws: Autoproj.workspace)
192
- c = ws.config.get('bundler.build', {})
193
+ c = ws.config.get("bundler.build", {})
193
194
  c.delete(gem_name)
194
- ws.config.set('bundler.build', c)
195
+ ws.config.set("bundler.build", c)
195
196
  end
196
197
 
197
198
  # @api private
@@ -202,7 +203,7 @@ module Autoproj
202
203
  # should be updated
203
204
  # @return [void]
204
205
  def self.apply_build_config(ws)
205
- root_dir = File.join(ws.prefix_dir, 'gems')
206
+ root_dir = File.join(ws.prefix_dir, "gems")
206
207
  current_config_path = File.join(root_dir, ".bundle", "config")
207
208
  current_config =
208
209
  if File.file?(current_config_path)
@@ -220,10 +221,10 @@ module Autoproj
220
221
  next(line) unless (m = line.match(/BUNDLE_BUILD__(.*): "(.*)"$/))
221
222
  next unless (desired_config = build_config.delete(m[1]))
222
223
 
223
- if m[2] != desired_config
224
- "BUNDLE_BUILD__#{m[1]}: \"#{desired_config}\""
225
- else
224
+ if m[2] == desired_config
226
225
  line
226
+ else
227
+ "BUNDLE_BUILD__#{m[1]}: \"#{desired_config}\""
227
228
  end
228
229
  end.compact
229
230
 
@@ -233,7 +234,7 @@ module Autoproj
233
234
 
234
235
  if new_config != current_config
235
236
  FileUtils.mkdir_p File.dirname(current_config_path)
236
- File.open(current_config_path, 'w') do |io|
237
+ File.open(current_config_path, "w") do |io|
237
238
  io.write new_config.join
238
239
  end
239
240
  end
@@ -249,28 +250,10 @@ module Autoproj
249
250
  # @param [Array<String>] system_rubylib the rubylib entries that are
250
251
  # set by the underlying ruby interpreter itself
251
252
  def update_env_rubylib(bundle_rubylib, system_rubylib = discover_rubylib)
252
- current = (ws.env.resolved_env['RUBYLIB'] || '')
253
+ current = (ws.env.resolved_env["RUBYLIB"] || "")
253
254
  .split(File::PATH_SEPARATOR) + system_rubylib
254
255
  (bundle_rubylib - current).each do |p|
255
- ws.env.add_path('RUBYLIB', p)
256
- end
257
- end
258
-
259
- # @api private
260
- #
261
- # Parse an osdep entry into a gem name and gem version
262
- #
263
- # The 'gem' entries in the osdep files can contain a version
264
- # specification. This method parses the two parts and return them
265
- #
266
- # @param [String] entry the osdep entry
267
- # @return [(String,String),(String,nil)] the gem name, and an
268
- # optional version specification
269
- def parse_package_entry(entry)
270
- if entry =~ /^([^><=~]*)([><=~]+.*)$/
271
- [$1.strip, $2.strip]
272
- else
273
- [entry]
256
+ ws.env.add_path("RUBYLIB", p)
274
257
  end
275
258
  end
276
259
 
@@ -320,21 +303,21 @@ module Autoproj
320
303
  )
321
304
  FileUtils.rm "#{gemfile}.lock" if update && File.file?("#{gemfile}.lock")
322
305
 
323
- options << '--path' << gem_path
306
+ options << "--path" << gem_path
324
307
  options << "--shebang" << Gem.ruby
325
308
  options << "--binstubs" << binstubs if binstubs
326
309
 
327
310
  apply_build_config(ws)
328
311
 
329
312
  connections = Set.new
330
- run_bundler(ws, 'install', *options,
313
+ run_bundler(ws, "install", *options,
331
314
  bundler_version: bundler_version,
332
315
  gem_home: gem_home, gemfile: gemfile) do |line|
333
316
  case line
334
317
  when /Installing (.*)/
335
318
  Autobuild.message " bundler: installing #{$1}"
336
319
  when /Fetching.*from (.*)/
337
- host = $1.gsub(/\.+$/, '')
320
+ host = $1.gsub(/\.+$/, "")
338
321
  unless connections.include?(host)
339
322
  Autobuild.message " bundler: connected to #{host}"
340
323
  connections << host
@@ -344,41 +327,42 @@ module Autoproj
344
327
  end
345
328
 
346
329
  def self.bundle_gem_path(ws, gem_name,
347
- bundler_version: ws.config.bundler_version,
348
- gem_home: nil, gemfile: nil)
330
+ bundler_version: ws.config.bundler_version,
331
+ gem_home: nil, gemfile: nil)
349
332
  path = String.new
350
333
  run_bundler(
351
- ws, 'show', gem_name,
334
+ ws, "show", gem_name,
352
335
  bundler_version: bundler_version, gem_home: gem_home,
353
- gemfile: gemfile) { |line| path << line }
336
+ gemfile: gemfile
337
+ ) { |line| path << line }
354
338
  path.chomp
355
339
  end
356
340
 
357
341
  def self.default_bundler(ws)
358
- File.join(ws.dot_autoproj_dir, 'bin', 'bundle')
342
+ File.join(ws.dot_autoproj_dir, "bin", "bundle")
359
343
  end
360
344
 
361
345
  def self.run_bundler(ws, *commandline,
362
- bundler_version: ws.config.bundler_version,
363
- gem_home: ws.config.gems_gem_home,
364
- gemfile: default_gemfile_path(ws))
365
- bundle = Autobuild.programs['bundle'] || default_bundler(ws)
346
+ bundler_version: ws.config.bundler_version,
347
+ gem_home: ws.config.gems_gem_home,
348
+ gemfile: default_gemfile_path(ws))
349
+ bundle = Autobuild.programs["bundle"] || default_bundler(ws)
366
350
 
367
351
  Autoproj.bundler_with_unbundled_env do
368
352
  bundler_version_env =
369
353
  if bundler_version
370
- { 'BUNDLER_VERSION' => bundler_version }
354
+ { "BUNDLER_VERSION" => bundler_version }
371
355
  else
372
356
  {}
373
357
  end
374
358
  target_env = Hash[
375
- 'GEM_HOME' => gem_home,
376
- 'GEM_PATH' => nil,
377
- 'BUNDLE_GEMFILE' => gemfile,
378
- 'RUBYOPT' => nil,
379
- 'RUBYLIB' => rubylib_for_bundler,
359
+ "GEM_HOME" => gem_home,
360
+ "GEM_PATH" => nil,
361
+ "BUNDLE_GEMFILE" => gemfile,
362
+ "RUBYOPT" => nil,
363
+ "RUBYLIB" => rubylib_for_bundler,
380
364
  ].merge(bundler_version_env)
381
- ws.run('autoproj', 'osdeps',
365
+ ws.run("autoproj", "osdeps",
382
366
  bundle, *commandline,
383
367
  working_directory: File.dirname(gemfile),
384
368
  env: target_env) { |line| yield(line) if block_given? }
@@ -386,7 +370,7 @@ module Autoproj
386
370
  end
387
371
 
388
372
  # Parse the contents of a gemfile into a set of
389
- def merge_gemfiles(*path, unlock: [])
373
+ def merge_gemfiles(*path, ruby_version: nil, unlock: [])
390
374
  gems_remotes = Set.new
391
375
  dependencies = Hash.new do |h, k|
392
376
  h[k] = Hash.new do |i, j|
@@ -400,21 +384,21 @@ module Autoproj
400
384
  begin Bundler::Dsl.evaluate(gemfile, nil, [])
401
385
  rescue Exception => e
402
386
  cleaned_message = e
403
- .message
404
- .gsub(/There was an error parsing([^:]+)/,
405
- "Error in gem definitions")
406
- .gsub(/# from.*/, '')
387
+ .message
388
+ .gsub(/There was an error parsing([^:]+)/,
389
+ "Error in gem definitions")
390
+ .gsub(/# from.*/, "")
407
391
  raise ConfigError, cleaned_message
408
392
  end
409
393
  gems_remotes |= bundler_def.send(:sources).rubygems_remotes.to_set
410
394
  bundler_def.dependencies.each do |d|
411
395
  d.groups.each do |group_name|
412
- if !d.platforms.empty?
396
+ if d.platforms.empty?
397
+ dependencies[group_name][""][d.name] = d
398
+ else
413
399
  d.platforms.each do |platform_name|
414
400
  dependencies[group_name][platform_name][d.name] = d
415
401
  end
416
- else
417
- dependencies[group_name][''][d.name] = d
418
402
  end
419
403
  end
420
404
  end
@@ -423,9 +407,12 @@ module Autoproj
423
407
  contents = []
424
408
  gems_remotes.each do |g|
425
409
  g = g.to_s
426
- g = g[0..-2] if g.end_with?('/')
410
+ g = g[0..-2] if g.end_with?("/")
427
411
  contents << "source '#{g}'"
428
412
  end
413
+ if ruby_version
414
+ contents << "ruby \"#{ruby_version}\" if respond_to?(:ruby)"
415
+ end
429
416
  valid_keys = %w[group groups git path glob name branch ref tag
430
417
  require submodules platform platforms type
431
418
  source install_if]
@@ -444,11 +431,11 @@ module Autoproj
444
431
  options = options.map { |k, v| "#{k}: \"#{v}\"" }
445
432
  end
446
433
  contents << [" #{platform_indent}gem \"#{d.name}\",
447
- \"#{d.requirement}\"", *options].join(', ')
434
+ \"#{d.requirement}\"", *options].join(", ")
448
435
  end
449
- contents << ' end' unless platform_name.empty?
436
+ contents << " end" unless platform_name.empty?
450
437
  end
451
- contents << 'end'
438
+ contents << "end"
452
439
  end
453
440
  contents.join("\n")
454
441
  end
@@ -456,7 +443,7 @@ module Autoproj
456
443
  def workspace_configuration_gemfiles
457
444
  gemfiles = []
458
445
  ws.manifest.each_package_set do |source|
459
- pkg_set_gemfile = File.join(source.local_dir, 'Gemfile')
446
+ pkg_set_gemfile = File.join(source.local_dir, "Gemfile")
460
447
  if source.local_dir && File.file?(pkg_set_gemfile)
461
448
  gemfiles << pkg_set_gemfile
462
449
  end
@@ -469,7 +456,58 @@ module Autoproj
469
456
  end
470
457
 
471
458
  def self.default_gemfile_path(ws)
472
- File.join(ws.prefix_dir, 'gems', 'Gemfile')
459
+ File.join(ws.prefix_dir, "gems", "Gemfile")
460
+ end
461
+
462
+ GemEntry = Struct.new :name, :version, :options do
463
+ def self.parse(object)
464
+ if object.respond_to?(:to_str)
465
+ parse_from_string(object)
466
+ elsif object.respond_to?(:to_hash)
467
+ parse_from_hash(object)
468
+ else
469
+ raise ArgumentError,
470
+ "expected #{object} to either be a string or a map"
471
+ end
472
+ end
473
+
474
+ # Parse an osdep entry string into a gem name and gem version
475
+ #
476
+ # The 'gem' entries in the osdep files can contain a version
477
+ # specification. This method parses the two parts and return them
478
+ #
479
+ # @param [String] entry the osdep entry
480
+ # @return [(String,String),(String,nil)] the gem name, and an
481
+ # optional version specification
482
+ def self.parse_from_string(entry)
483
+ if entry =~ /^([^><=~]*)([><=~]+.*)$/
484
+ GemEntry.new($1.strip, $2.strip, {})
485
+ else
486
+ GemEntry.new(entry, nil, {})
487
+ end
488
+ end
489
+
490
+ # Parse an option hash into a GemEntry
491
+ def self.parse_from_hash(hash)
492
+ hash = hash.dup
493
+ unless (name = hash.delete("name"))
494
+ raise ArgumentError,
495
+ "expected gem entry #{hash} to have at least a 'name' key"
496
+ end
497
+
498
+ version = hash.delete("version")
499
+ GemEntry.new(name, version, hash)
500
+ end
501
+
502
+ def to_gemfile_line
503
+ options_s = options.map { |k, v| "#{k}: \"#{v}\"" }.join(", ")
504
+ entries = [
505
+ "\"#{name}\"",
506
+ ("\"#{version}\"" if version),
507
+ (options_s unless options_s.empty?)
508
+ ].compact
509
+ "gem #{entries.join(', ')}"
510
+ end
473
511
  end
474
512
 
475
513
  def install(gems, filter_uptodate_packages: false, install_only: false)
@@ -486,40 +524,38 @@ module Autoproj
486
524
  backup_files(backups)
487
525
  unless File.file?("#{gemfile_path}.orig")
488
526
  Ops.atomic_write("#{gemfile_path}.orig") do |io|
489
- dot_autoproj_gemfile = File.join(ws.dot_autoproj_dir, 'Gemfile')
527
+ dot_autoproj_gemfile = File.join(ws.dot_autoproj_dir, "Gemfile")
490
528
  io.puts "eval_gemfile \"#{dot_autoproj_gemfile}\""
491
529
  end
492
530
  end
493
531
 
494
- gemfiles = workspace_configuration_gemfiles
495
- gemfiles << File.join(ws.dot_autoproj_dir, 'Gemfile')
532
+ gemfiles = []
496
533
 
497
- # Save the osdeps entries in a temporary gemfile and finally
498
- # merge the whole lot of it
499
- gemfile_contents = Tempfile.open 'autoproj-gemfile' do |io|
500
- gems.sort.each do |name|
501
- name, version = parse_package_entry(name)
502
- io.puts "gem \"#{name}\", \"#{version || '>= 0'}\""
503
- end
504
- io.flush
505
- gemfiles.unshift io.path
506
- # The autoproj gemfile needs to be last, we really don't
507
- # want to mess it up
508
- merge_gemfiles(*gemfiles)
534
+ unless gems.empty?
535
+ osdeps_gemfile_io = prepare_osdeps_gemfile(gems)
536
+ gemfiles << osdeps_gemfile_io.path
509
537
  end
510
538
 
539
+ gemfiles += workspace_configuration_gemfiles
540
+ # The autoproj gemfile needs to be last, we really don't
541
+ # want to mess it up
542
+ gemfiles << File.join(ws.dot_autoproj_dir, "Gemfile")
543
+
544
+ ruby_version = RUBY_VERSION.gsub(/\.\d+$/, ".0")
545
+ gemfile_contents =
546
+ merge_gemfiles(*gemfiles, ruby_version: "~> #{ruby_version}")
547
+
511
548
  FileUtils.mkdir_p root_dir
512
549
  updated = (!File.exist?(gemfile_path) ||
513
550
  File.read(gemfile_path) != gemfile_contents)
514
551
  if updated
515
552
  Ops.atomic_write(gemfile_path) do |io|
516
- io.puts "ruby \"#{RUBY_VERSION}\" if respond_to?(:ruby)"
517
553
  io.puts gemfile_contents
518
554
  end
519
555
  end
520
556
 
521
- options = Array.new
522
- binstubs_path = File.join(root_dir, 'bin')
557
+ options = []
558
+ binstubs_path = File.join(root_dir, "bin")
523
559
  if updated || !install_only || !File.file?("#{gemfile_path}.lock")
524
560
  self.class.run_bundler_install(ws, gemfile_path, *options,
525
561
  binstubs: binstubs_path)
@@ -539,20 +575,40 @@ module Autoproj
539
575
  raise
540
576
  ensure
541
577
  if binstubs_path
542
- FileUtils.rm_f File.join(binstubs_path, 'bundle')
543
- FileUtils.rm_f File.join(binstubs_path, 'bundler')
578
+ FileUtils.rm_f File.join(binstubs_path, "bundle")
579
+ FileUtils.rm_f File.join(binstubs_path, "bundler")
544
580
  end
545
581
  backup_clean(backups)
546
582
  end
547
583
 
584
+ # Prepare a Gemfile that contains osdeps gem declarations
585
+ #
586
+ # @param [Array<String,Hash>] gems osdeps declarations as understood
587
+ # by {GemEntry.parse}
588
+ # @return [File]
589
+ def prepare_osdeps_gemfile(gems)
590
+ io = Tempfile.open "autoproj-gemfile"
591
+ io.puts "source \"https://rubygems.org\""
592
+ gems.map { |entry| GemEntry.parse(entry) }
593
+ .sort_by(&:name)
594
+ .each { |entry| io.puts entry.to_gemfile_line }
595
+
596
+ io.flush
597
+ io
598
+ rescue Exception
599
+ io&.close
600
+ raise
601
+ end
602
+
548
603
  def discover_rubylib
549
- require 'bundler'
550
- Tempfile.open 'autoproj-rubylib' do |io|
604
+ require "bundler"
605
+ Tempfile.open "autoproj-rubylib" do |io|
551
606
  result = Autoproj.bundler_unbundled_system(
552
- Hash['RUBYLIB' => nil],
553
- Autobuild.tool('ruby'), '-e', 'puts $LOAD_PATH',
607
+ Hash["RUBYLIB" => nil],
608
+ Autobuild.tool("ruby"), "-e", "puts $LOAD_PATH",
554
609
  out: io,
555
- err: '/dev/null')
610
+ err: "/dev/null"
611
+ )
556
612
  if result
557
613
  io.rewind
558
614
  io.readlines.map(&:chomp).find_all { |l| !l.empty? }
@@ -566,19 +622,20 @@ module Autoproj
566
622
  end
567
623
 
568
624
  def discover_bundle_rubylib(silent_errors: false)
569
- require 'bundler'
570
- gemfile = File.join(ws.prefix_dir, 'gems', 'Gemfile')
625
+ require "bundler"
626
+ gemfile = File.join(ws.prefix_dir, "gems", "Gemfile")
571
627
  silent_redirect = Hash.new
572
628
  silent_redirect[:err] = :close if silent_errors
573
629
  env = ws.env.resolved_env
574
- Tempfile.open 'autoproj-rubylib' do |io|
630
+ Tempfile.open "autoproj-rubylib" do |io|
575
631
  result = Autoproj.bundler_unbundled_system(
576
- Hash['GEM_HOME' => env['GEM_HOME'], 'GEM_PATH' => env['GEM_PATH'],
577
- 'BUNDLE_GEMFILE' => gemfile, 'RUBYOPT' => nil,
578
- 'RUBYLIB' => self.class.rubylib_for_bundler],
579
- Autobuild.tool('ruby'), '-rbundler/setup',
580
- '-e', 'puts $LOAD_PATH',
581
- out: io, **silent_redirect)
632
+ Hash["GEM_HOME" => env["GEM_HOME"], "GEM_PATH" => env["GEM_PATH"],
633
+ "BUNDLE_GEMFILE" => gemfile, "RUBYOPT" => nil,
634
+ "RUBYLIB" => self.class.rubylib_for_bundler],
635
+ Autobuild.tool("ruby"), "-rbundler/setup",
636
+ "-e", "puts $LOAD_PATH",
637
+ out: io, **silent_redirect
638
+ )
582
639
 
583
640
  if result
584
641
  io.rewind