autoproj 1.9.7.rc19 → 1.9.7.rc20

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.
@@ -133,7 +133,12 @@ module Autoproj
133
133
  # Base class for all package managers. Subclasses must add the
134
134
  # #install(packages) method and may add the
135
135
  # #filter_uptodate_packages(packages) method
136
+ #
137
+ # Package managers must be registered in PACKAGE_HANDLERS and
138
+ # (if applicable) OS_PACKAGE_HANDLERS.
136
139
  class Manager
140
+ # @return [Array<String>] the various names this package manager is
141
+ # known about
137
142
  attr_reader :names
138
143
 
139
144
  attr_writer :enabled
@@ -142,12 +147,18 @@ module Autoproj
142
147
  attr_writer :silent
143
148
  def silent?; !!@silent end
144
149
 
150
+ # Create a package manager registered with various names
151
+ #
152
+ # @param [Array<String>] names the package manager names. It MUST be
153
+ # different from the OS names that autoproj uses. See the comment
154
+ # for OS_PACKAGE_HANDLERS for an explanation
145
155
  def initialize(names = [])
146
156
  @names = names.dup
147
157
  @enabled = true
148
158
  @silent = true
149
159
  end
150
160
 
161
+ # The primary name for this package manager
151
162
  def name
152
163
  names.first
153
164
  end
@@ -201,7 +212,7 @@ module Autoproj
201
212
  # Base class for all package managers that simply require the call of a
202
213
  # shell script to install packages (e.g. yum, apt, ...)
203
214
  class ShellScriptManager < Manager
204
- def self.execute_as_root(script, with_locking)
215
+ def self.execute(script, with_locking, with_root)
205
216
  if with_locking
206
217
  File.open('/tmp/autoproj_osdeps_lock', 'w') do |lock_io|
207
218
  begin
@@ -209,7 +220,7 @@ module Autoproj
209
220
  Autoproj.message " waiting for other autoproj instances to finish their osdeps installation"
210
221
  sleep 5
211
222
  end
212
- return execute_as_root(script, false)
223
+ return execute(script, false,with_root)
213
224
  ensure
214
225
  lock_io.flock(File::LOCK_UN)
215
226
  end
@@ -219,7 +230,7 @@ module Autoproj
219
230
  sudo = Autobuild.tool_in_path('sudo')
220
231
  Tempfile.open('osdeps_sh') do |io|
221
232
  io.puts "#! /bin/bash"
222
- io.puts GAIN_ROOT_ACCESS % [sudo]
233
+ io.puts GAIN_ROOT_ACCESS % [sudo] if with_root
223
234
  io.write script
224
235
  io.flush
225
236
  Autobuild::Subprocess.run 'autoproj', 'osdeps', '/bin/bash', io.path
@@ -234,18 +245,78 @@ if test `id -u` != "0"; then
234
245
  fi
235
246
  EOSCRIPT
236
247
 
248
+ # Overrides the {#needs_locking?} flag
237
249
  attr_writer :needs_locking
250
+ # Whether two autoproj instances can run this package manager at the
251
+ # same time
252
+ #
253
+ # This declares if this package manager cannot be used concurrently.
254
+ # If it is the case, autoproj will ensure that there is no two
255
+ # autoproj instances running this package manager at the same time
256
+ #
257
+ # @return [Boolean]
258
+ # @see needs_locking=
238
259
  def needs_locking?; !!@needs_locking end
239
260
 
261
+ # Overrides the {#needs_root?} flag
262
+ attr_writer :needs_root
263
+ # Whether this package manager needs root access.
264
+ #
265
+ # This declares if the command line(s) for this package manager
266
+ # should be started as root. Root access is provided using sudo
267
+ #
268
+ # @return [Boolean]
269
+ # @see needs_root=
270
+ def needs_root?; !!@needs_root end
271
+
272
+ # Command line used by autoproj to install packages
273
+ #
274
+ # Since it is to be used for automated install by autoproj, it
275
+ # should not require any interaction with the user. When generating
276
+ # the command line, the %s slot is replaced by the quoted package
277
+ # name(s).
278
+ #
279
+ # @return [String] a command line pattern that allows to install
280
+ # packages without user interaction. It is used when a package
281
+ # should be installed by autoproj automatically
240
282
  attr_reader :auto_install_cmd
283
+ # Command line displayed to the user to install packages
284
+ #
285
+ # When generating the command line, the %s slot is replaced by the
286
+ # quoted package name(s).
287
+ #
288
+ # @return [String] a command line pattern that allows to install
289
+ # packages with user interaction. It is displayed to the
290
+ # user when it chose to not let autoproj install packages for this
291
+ # package manager automatically
241
292
  attr_reader :user_install_cmd
242
293
 
243
- def initialize(names, needs_locking, user_install_cmd, auto_install_cmd)
294
+ # @param [Array<String>] names the package managers names, see
295
+ # {#names}
296
+ # @param [Boolean] needs_locking whether this package manager can be
297
+ # started by two separate autoproj instances at the same time. See
298
+ # {#needs_locking?}
299
+ # @param [String] user_install_cmd the user-visible command line. See
300
+ # {#user_install_cmd}
301
+ # @param [String] auto_install_cmd the command line used by autoproj
302
+ # itself, see {#auto_install_cmd}.
303
+ # @param [Boolean] needs_root if the command lines should be started
304
+ # as root or not. See {#needs_root?}
305
+ def initialize(names, needs_locking, user_install_cmd, auto_install_cmd,needs_root=true)
244
306
  super(names)
245
- @needs_locking, @user_install_cmd, @auto_install_cmd =
246
- needs_locking, user_install_cmd, auto_install_cmd
307
+ @needs_locking, @user_install_cmd, @auto_install_cmd,@needs_root =
308
+ needs_locking, user_install_cmd, auto_install_cmd, needs_root
247
309
  end
248
310
 
311
+ # Generate the shell script that would allow the user to install
312
+ # the given packages
313
+ #
314
+ # @param [Array<String>] os_packages the name of the packages to be
315
+ # installed
316
+ # @option options [String] :user_install_cmd (#user_install_cmd) the
317
+ # command-line pattern that should be used to generate the script.
318
+ # If given, it overrides the default value stored in
319
+ # {#user_install_cmd]
249
320
  def generate_user_os_script(os_packages, options = Hash.new)
250
321
  user_install_cmd = options[:user_install_cmd] || self.user_install_cmd
251
322
  if user_install_cmd
@@ -254,11 +325,28 @@ fi
254
325
  end
255
326
  end
256
327
 
328
+ # Generate the shell script that should be executed by autoproj to
329
+ # install the given packages
330
+ #
331
+ # @param [Array<String>] os_packages the name of the packages to be
332
+ # installed
333
+ # @option options [String] :auto_install_cmd (#auto_install_cmd) the
334
+ # command-line pattern that should be used to generate the script.
335
+ # If given, it overrides the default value stored in
336
+ # {#auto_install_cmd]
257
337
  def generate_auto_os_script(os_packages, options = Hash.new)
258
338
  auto_install_cmd = options[:auto_install_cmd] || self.auto_install_cmd
259
339
  (auto_install_cmd % [os_packages.join("' '")])
260
340
  end
261
341
 
342
+ # Handles interaction with the user
343
+ #
344
+ # This method will verify whether the user required autoproj to
345
+ # install packages from this package manager automatically. It
346
+ # displays a relevant message if it is not the case.
347
+ #
348
+ # @return [Boolean] true if the packages should be installed
349
+ # automatically, false otherwise
262
350
  def osdeps_interaction(os_packages, shell_script)
263
351
  if OSDependencies.force_osdeps
264
352
  return true
@@ -293,6 +381,17 @@ fi
293
381
  false
294
382
  end
295
383
 
384
+ # Install packages using this package manager
385
+ #
386
+ # @param [Array<String>] packages the name of the packages that
387
+ # should be installed
388
+ # @option options [String] :user_install_cmd (#user_install_cmd) the
389
+ # command line that should be displayed to the user to install said
390
+ # packages. See the option in {#generate_user_os_script}
391
+ # @option options [String] :auto_install_cmd (#auto_install_cmd) the
392
+ # command line that should be used by autoproj to install said
393
+ # packages. See the option in {#generate_auto_os_script}
394
+ # @return [Boolean] true if packages got installed, false otherwise
296
395
  def install(packages, options = Hash.new)
297
396
  handled_os = OSDependencies.supported_operating_system?
298
397
  if handled_os
@@ -306,7 +405,7 @@ fi
306
405
  Autoproj.message "Generating installation script for non-ruby OS dependencies"
307
406
  Autoproj.message shell_script
308
407
  end
309
- ShellScriptManager.execute_as_root(shell_script, needs_locking?)
408
+ ShellScriptManager.execute(shell_script, needs_locking?,needs_root?)
310
409
  return true
311
410
  end
312
411
  false
@@ -317,12 +416,57 @@ fi
317
416
  # their package manager
318
417
  class PortManager < ShellScriptManager
319
418
  def initialize
320
- super(['port'], true,
419
+ super(['macports'], true,
321
420
  "port install '%s'",
322
421
  "port install '%s'")
323
422
  end
324
423
  end
325
424
 
425
+ # Package manager interface for Mac OS using homebrew as
426
+ # its package manager
427
+ class HomebrewManager < ShellScriptManager
428
+ def initialize
429
+ super(['brew'], true,
430
+ "brew install '%s'",
431
+ "brew install '%s'",
432
+ false)
433
+ end
434
+
435
+ def filter_uptodate_packages(packages)
436
+ # TODO there might be duplicates in packages which should be fixed
437
+ # somewhere else
438
+ packages = packages.uniq
439
+ result = `brew info --json=v1 '#{packages.join("' '")}'`
440
+ result = begin
441
+ result = JSON.parse(result)
442
+ if packages.size == 1
443
+ [result]
444
+ else
445
+ result
446
+ end
447
+ rescue JSON::ParserError
448
+ if result && !result.empty?
449
+ Autoproj.warn "Error while parsing result of brew info --json=v1"
450
+ else
451
+ # one of the packages is unknown fallback to install all
452
+ # packaes which will complain about it
453
+ end
454
+ return packages
455
+ end
456
+ # fall back if something else went wrong
457
+ if packages.size != result.size
458
+ Autoproj.warn "brew info returns less or more packages when requested. Falling back to install all packages"
459
+ return packages
460
+ end
461
+
462
+ new_packages = []
463
+ result.each do |pkg|
464
+ new_packages << pkg["name"] if pkg["installed"].empty?
465
+ end
466
+ new_packages
467
+ end
468
+ end
469
+
326
470
  # Package manager interface for systems that use pacman (i.e. arch) as
327
471
  # their package manager
328
472
  class PacmanManager < ShellScriptManager
@@ -626,7 +770,7 @@ fi
626
770
  else prerelease = Array.new
627
771
  end
628
772
  (non_prerelease + prerelease).
629
- map { |(n, v, _), _| [n, v] }
773
+ map { |n, v, _| [n, v] }
630
774
 
631
775
  else # Post RubyGems-2.0
632
776
  type = if GemManager.with_prerelease then :complete
@@ -874,17 +1018,30 @@ fi
874
1018
  PackageManagers::GemManager,
875
1019
  PackageManagers::EmergeManager,
876
1020
  PackageManagers::PacmanManager,
877
- PackageManagers::PacmanManager,
1021
+ PackageManagers::HomebrewManager,
878
1022
  PackageManagers::YumManager,
879
1023
  PackageManagers::PortManager,
880
1024
  PackageManagers::ZypperManager,
881
1025
  PackageManagers::PipManager]
1026
+
1027
+ # Mapping from OS name to package manager name
1028
+ #
1029
+ # Package handlers and OSes MUST have different names. The former are
1030
+ # used to resolve packages and the latter to resolve OSes in the osdeps.
1031
+ # Since one can force the use of a package manager in any OS by adding a
1032
+ # package manager entry, as e.g.
1033
+ #
1034
+ # ubuntu:
1035
+ # homebrew: package
1036
+ #
1037
+ # we need to be able to separate between OS and package manager names.
882
1038
  OS_PACKAGE_HANDLERS = {
883
1039
  'debian' => 'apt-dpkg',
884
1040
  'gentoo' => 'emerge',
885
1041
  'arch' => 'pacman',
886
1042
  'fedora' => 'yum',
887
- 'darwin' => 'port',
1043
+ 'macos-port' => 'macports',
1044
+ 'macos-brew' => 'brew',
888
1045
  'opensuse' => 'zypper'
889
1046
  }
890
1047
 
@@ -1048,7 +1205,22 @@ fi
1048
1205
  [['arch'], []]
1049
1206
  elsif Autobuild.macos?
1050
1207
  version=`sw_vers | head -2 | tail -1`.split(":")[1]
1051
- [['darwin'], [version.strip]]
1208
+ manager =
1209
+ if ENV['AUTOPROJ_MACOSX_PACKAGE_MANAGER']
1210
+ ENV['AUTOPROJ_MACOSX_PACKAGE_MANAGER']
1211
+ else 'macos-brew'
1212
+ end
1213
+ if !OS_PACKAGE_HANDLERS.include?(manager)
1214
+ known_managers = OS_PACKAGE_HANDLERS.keys.grep(/^macos/)
1215
+ raise ArgumentError, "#{manager} is not a known MacOSX package manager. Known package managers are #{known_managers.join(", ")}"
1216
+ end
1217
+
1218
+ managers =
1219
+ if manager == 'macos-port'
1220
+ [manager, 'port']
1221
+ else [manager]
1222
+ end
1223
+ [[*managers, 'darwin'], [version.strip]]
1052
1224
  elsif Autobuild.windows?
1053
1225
  [['windows'], []]
1054
1226
  elsif File.exists?('/etc/SuSE-release')
@@ -2344,12 +2516,14 @@ ruby19:
2344
2516
  '17':
2345
2517
  - ruby
2346
2518
  - rubygems
2347
- darwin:
2519
+ macos-port:
2348
2520
  - ruby19
2349
2521
  - rake
2522
+ macos-brew:
2523
+ - ruby193
2524
+ default: nonexistent
2350
2525
  opensuse: ruby19-devel
2351
2526
  arch: ignore
2352
- default: nonexistent
2353
2527
  ruby20:
2354
2528
  debian:
2355
2529
  - ruby2.0
@@ -2395,7 +2569,8 @@ git:
2395
2569
  gentoo: dev-vcs/git
2396
2570
  arch: git
2397
2571
  fedora: git
2398
- darwin: git-core
2572
+ macos-port: git-core
2573
+ macos-brew: git
2399
2574
  opensuse: git
2400
2575
  hg:
2401
2576
  debian,ubuntu: mercurial
@@ -2450,9 +2625,11 @@ archive:
2450
2625
  fedora:
2451
2626
  - tar
2452
2627
  - unzip
2453
- darwin:
2628
+ macos-port:
2454
2629
  - gnutar
2455
2630
  - unzip
2631
+ macos-brew:
2632
+ - gnu-tar
2456
2633
  opensuse:
2457
2634
  - tar
2458
2635
  - unzip
@@ -19,6 +19,7 @@ require 'autoproj/cmdline'
19
19
  require 'autoproj/query'
20
20
  require 'logger'
21
21
  require 'utilrb/logger'
22
+ require 'json'
22
23
 
23
24
  module Autoproj
24
25
  class << self
@@ -225,7 +225,7 @@ module Autoproj
225
225
  elsif Autoproj.has_config_key?('autoproj_use_prerelease')
226
226
  Autoproj.user_config('autoproj_use_prerelease')
227
227
  end
228
- Autoproj.change_option "autoproj_use_prerelease", use_prerelease, true
228
+ Autoproj.change_option "autoproj_use_prerelease", (use_prerelease ? true : false), true
229
229
 
230
230
  did_update =
231
231
  begin
@@ -32,9 +32,12 @@ ruby19:
32
32
  "17":
33
33
  - ruby
34
34
  - rubygems
35
- darwin:
35
+ macos-port:
36
36
  - ruby19
37
37
  - rake
38
+ macos-brew:
39
+ - ruby193
40
+ default: nonexistent
38
41
  opensuse: ruby19-devel
39
42
  arch: ignore # on arch, if ruby is installed then so is the supporting stuff
40
43
  default: nonexistent
@@ -84,7 +87,8 @@ git:
84
87
  gentoo: dev-vcs/git
85
88
  arch: git
86
89
  fedora: git
87
- darwin: git-core
90
+ macos-port: git-core
91
+ macos-brew: git
88
92
  opensuse: git
89
93
 
90
94
  hg:
@@ -144,9 +148,11 @@ archive:
144
148
  fedora:
145
149
  - tar
146
150
  - unzip
147
- darwin:
151
+ macos-port:
148
152
  - gnutar
149
153
  - unzip
154
+ macos-brew:
155
+ - gnu-tar
150
156
  opensuse:
151
157
  - tar
152
158
  - unzip
@@ -6,7 +6,12 @@ module Autoproj
6
6
  # Base class for all package managers. Subclasses must add the
7
7
  # #install(packages) method and may add the
8
8
  # #filter_uptodate_packages(packages) method
9
+ #
10
+ # Package managers must be registered in PACKAGE_HANDLERS and
11
+ # (if applicable) OS_PACKAGE_HANDLERS.
9
12
  class Manager
13
+ # @return [Array<String>] the various names this package manager is
14
+ # known about
10
15
  attr_reader :names
11
16
 
12
17
  attr_writer :enabled
@@ -15,12 +20,18 @@ module Autoproj
15
20
  attr_writer :silent
16
21
  def silent?; !!@silent end
17
22
 
23
+ # Create a package manager registered with various names
24
+ #
25
+ # @param [Array<String>] names the package manager names. It MUST be
26
+ # different from the OS names that autoproj uses. See the comment
27
+ # for OS_PACKAGE_HANDLERS for an explanation
18
28
  def initialize(names = [])
19
29
  @names = names.dup
20
30
  @enabled = true
21
31
  @silent = true
22
32
  end
23
33
 
34
+ # The primary name for this package manager
24
35
  def name
25
36
  names.first
26
37
  end
@@ -74,7 +85,7 @@ module Autoproj
74
85
  # Base class for all package managers that simply require the call of a
75
86
  # shell script to install packages (e.g. yum, apt, ...)
76
87
  class ShellScriptManager < Manager
77
- def self.execute_as_root(script, with_locking)
88
+ def self.execute(script, with_locking, with_root)
78
89
  if with_locking
79
90
  File.open('/tmp/autoproj_osdeps_lock', 'w') do |lock_io|
80
91
  begin
@@ -82,7 +93,7 @@ module Autoproj
82
93
  Autoproj.message " waiting for other autoproj instances to finish their osdeps installation"
83
94
  sleep 5
84
95
  end
85
- return execute_as_root(script, false)
96
+ return execute(script, false,with_root)
86
97
  ensure
87
98
  lock_io.flock(File::LOCK_UN)
88
99
  end
@@ -92,7 +103,7 @@ module Autoproj
92
103
  sudo = Autobuild.tool_in_path('sudo')
93
104
  Tempfile.open('osdeps_sh') do |io|
94
105
  io.puts "#! /bin/bash"
95
- io.puts GAIN_ROOT_ACCESS % [sudo]
106
+ io.puts GAIN_ROOT_ACCESS % [sudo] if with_root
96
107
  io.write script
97
108
  io.flush
98
109
  Autobuild::Subprocess.run 'autoproj', 'osdeps', '/bin/bash', io.path
@@ -107,18 +118,78 @@ if test `id -u` != "0"; then
107
118
  fi
108
119
  EOSCRIPT
109
120
 
121
+ # Overrides the {#needs_locking?} flag
110
122
  attr_writer :needs_locking
123
+ # Whether two autoproj instances can run this package manager at the
124
+ # same time
125
+ #
126
+ # This declares if this package manager cannot be used concurrently.
127
+ # If it is the case, autoproj will ensure that there is no two
128
+ # autoproj instances running this package manager at the same time
129
+ #
130
+ # @return [Boolean]
131
+ # @see needs_locking=
111
132
  def needs_locking?; !!@needs_locking end
112
133
 
134
+ # Overrides the {#needs_root?} flag
135
+ attr_writer :needs_root
136
+ # Whether this package manager needs root access.
137
+ #
138
+ # This declares if the command line(s) for this package manager
139
+ # should be started as root. Root access is provided using sudo
140
+ #
141
+ # @return [Boolean]
142
+ # @see needs_root=
143
+ def needs_root?; !!@needs_root end
144
+
145
+ # Command line used by autoproj to install packages
146
+ #
147
+ # Since it is to be used for automated install by autoproj, it
148
+ # should not require any interaction with the user. When generating
149
+ # the command line, the %s slot is replaced by the quoted package
150
+ # name(s).
151
+ #
152
+ # @return [String] a command line pattern that allows to install
153
+ # packages without user interaction. It is used when a package
154
+ # should be installed by autoproj automatically
113
155
  attr_reader :auto_install_cmd
156
+ # Command line displayed to the user to install packages
157
+ #
158
+ # When generating the command line, the %s slot is replaced by the
159
+ # quoted package name(s).
160
+ #
161
+ # @return [String] a command line pattern that allows to install
162
+ # packages with user interaction. It is displayed to the
163
+ # user when it chose to not let autoproj install packages for this
164
+ # package manager automatically
114
165
  attr_reader :user_install_cmd
115
166
 
116
- def initialize(names, needs_locking, user_install_cmd, auto_install_cmd)
167
+ # @param [Array<String>] names the package managers names, see
168
+ # {#names}
169
+ # @param [Boolean] needs_locking whether this package manager can be
170
+ # started by two separate autoproj instances at the same time. See
171
+ # {#needs_locking?}
172
+ # @param [String] user_install_cmd the user-visible command line. See
173
+ # {#user_install_cmd}
174
+ # @param [String] auto_install_cmd the command line used by autoproj
175
+ # itself, see {#auto_install_cmd}.
176
+ # @param [Boolean] needs_root if the command lines should be started
177
+ # as root or not. See {#needs_root?}
178
+ def initialize(names, needs_locking, user_install_cmd, auto_install_cmd,needs_root=true)
117
179
  super(names)
118
- @needs_locking, @user_install_cmd, @auto_install_cmd =
119
- needs_locking, user_install_cmd, auto_install_cmd
180
+ @needs_locking, @user_install_cmd, @auto_install_cmd,@needs_root =
181
+ needs_locking, user_install_cmd, auto_install_cmd, needs_root
120
182
  end
121
183
 
184
+ # Generate the shell script that would allow the user to install
185
+ # the given packages
186
+ #
187
+ # @param [Array<String>] os_packages the name of the packages to be
188
+ # installed
189
+ # @option options [String] :user_install_cmd (#user_install_cmd) the
190
+ # command-line pattern that should be used to generate the script.
191
+ # If given, it overrides the default value stored in
192
+ # {#user_install_cmd]
122
193
  def generate_user_os_script(os_packages, options = Hash.new)
123
194
  user_install_cmd = options[:user_install_cmd] || self.user_install_cmd
124
195
  if user_install_cmd
@@ -127,11 +198,28 @@ fi
127
198
  end
128
199
  end
129
200
 
201
+ # Generate the shell script that should be executed by autoproj to
202
+ # install the given packages
203
+ #
204
+ # @param [Array<String>] os_packages the name of the packages to be
205
+ # installed
206
+ # @option options [String] :auto_install_cmd (#auto_install_cmd) the
207
+ # command-line pattern that should be used to generate the script.
208
+ # If given, it overrides the default value stored in
209
+ # {#auto_install_cmd]
130
210
  def generate_auto_os_script(os_packages, options = Hash.new)
131
211
  auto_install_cmd = options[:auto_install_cmd] || self.auto_install_cmd
132
212
  (auto_install_cmd % [os_packages.join("' '")])
133
213
  end
134
214
 
215
+ # Handles interaction with the user
216
+ #
217
+ # This method will verify whether the user required autoproj to
218
+ # install packages from this package manager automatically. It
219
+ # displays a relevant message if it is not the case.
220
+ #
221
+ # @return [Boolean] true if the packages should be installed
222
+ # automatically, false otherwise
135
223
  def osdeps_interaction(os_packages, shell_script)
136
224
  if OSDependencies.force_osdeps
137
225
  return true
@@ -166,6 +254,17 @@ fi
166
254
  false
167
255
  end
168
256
 
257
+ # Install packages using this package manager
258
+ #
259
+ # @param [Array<String>] packages the name of the packages that
260
+ # should be installed
261
+ # @option options [String] :user_install_cmd (#user_install_cmd) the
262
+ # command line that should be displayed to the user to install said
263
+ # packages. See the option in {#generate_user_os_script}
264
+ # @option options [String] :auto_install_cmd (#auto_install_cmd) the
265
+ # command line that should be used by autoproj to install said
266
+ # packages. See the option in {#generate_auto_os_script}
267
+ # @return [Boolean] true if packages got installed, false otherwise
169
268
  def install(packages, options = Hash.new)
170
269
  handled_os = OSDependencies.supported_operating_system?
171
270
  if handled_os
@@ -179,7 +278,7 @@ fi
179
278
  Autoproj.message "Generating installation script for non-ruby OS dependencies"
180
279
  Autoproj.message shell_script
181
280
  end
182
- ShellScriptManager.execute_as_root(shell_script, needs_locking?)
281
+ ShellScriptManager.execute(shell_script, needs_locking?,needs_root?)
183
282
  return true
184
283
  end
185
284
  false
@@ -190,12 +289,57 @@ fi
190
289
  # their package manager
191
290
  class PortManager < ShellScriptManager
192
291
  def initialize
193
- super(['port'], true,
292
+ super(['macports'], true,
194
293
  "port install '%s'",
195
294
  "port install '%s'")
196
295
  end
197
296
  end
198
297
 
298
+ # Package manager interface for Mac OS using homebrew as
299
+ # its package manager
300
+ class HomebrewManager < ShellScriptManager
301
+ def initialize
302
+ super(['brew'], true,
303
+ "brew install '%s'",
304
+ "brew install '%s'",
305
+ false)
306
+ end
307
+
308
+ def filter_uptodate_packages(packages)
309
+ # TODO there might be duplicates in packages which should be fixed
310
+ # somewhere else
311
+ packages = packages.uniq
312
+ result = `brew info --json=v1 '#{packages.join("' '")}'`
313
+ result = begin
314
+ result = JSON.parse(result)
315
+ if packages.size == 1
316
+ [result]
317
+ else
318
+ result
319
+ end
320
+ rescue JSON::ParserError
321
+ if result && !result.empty?
322
+ Autoproj.warn "Error while parsing result of brew info --json=v1"
323
+ else
324
+ # one of the packages is unknown fallback to install all
325
+ # packaes which will complain about it
326
+ end
327
+ return packages
328
+ end
329
+ # fall back if something else went wrong
330
+ if packages.size != result.size
331
+ Autoproj.warn "brew info returns less or more packages when requested. Falling back to install all packages"
332
+ return packages
333
+ end
334
+
335
+ new_packages = []
336
+ result.each do |pkg|
337
+ new_packages << pkg["name"] if pkg["installed"].empty?
338
+ end
339
+ new_packages
340
+ end
341
+ end
342
+
199
343
  # Package manager interface for systems that use pacman (i.e. arch) as
200
344
  # their package manager
201
345
  class PacmanManager < ShellScriptManager
@@ -499,7 +643,7 @@ fi
499
643
  else prerelease = Array.new
500
644
  end
501
645
  (non_prerelease + prerelease).
502
- map { |(n, v, _), _| [n, v] }
646
+ map { |n, v, _| [n, v] }
503
647
 
504
648
  else # Post RubyGems-2.0
505
649
  type = if GemManager.with_prerelease then :complete
@@ -747,17 +891,30 @@ fi
747
891
  PackageManagers::GemManager,
748
892
  PackageManagers::EmergeManager,
749
893
  PackageManagers::PacmanManager,
750
- PackageManagers::PacmanManager,
894
+ PackageManagers::HomebrewManager,
751
895
  PackageManagers::YumManager,
752
896
  PackageManagers::PortManager,
753
897
  PackageManagers::ZypperManager,
754
898
  PackageManagers::PipManager]
899
+
900
+ # Mapping from OS name to package manager name
901
+ #
902
+ # Package handlers and OSes MUST have different names. The former are
903
+ # used to resolve packages and the latter to resolve OSes in the osdeps.
904
+ # Since one can force the use of a package manager in any OS by adding a
905
+ # package manager entry, as e.g.
906
+ #
907
+ # ubuntu:
908
+ # homebrew: package
909
+ #
910
+ # we need to be able to separate between OS and package manager names.
755
911
  OS_PACKAGE_HANDLERS = {
756
912
  'debian' => 'apt-dpkg',
757
913
  'gentoo' => 'emerge',
758
914
  'arch' => 'pacman',
759
915
  'fedora' => 'yum',
760
- 'darwin' => 'port',
916
+ 'macos-port' => 'macports',
917
+ 'macos-brew' => 'brew',
761
918
  'opensuse' => 'zypper'
762
919
  }
763
920
 
@@ -921,7 +1078,22 @@ fi
921
1078
  [['arch'], []]
922
1079
  elsif Autobuild.macos?
923
1080
  version=`sw_vers | head -2 | tail -1`.split(":")[1]
924
- [['darwin'], [version.strip]]
1081
+ manager =
1082
+ if ENV['AUTOPROJ_MACOSX_PACKAGE_MANAGER']
1083
+ ENV['AUTOPROJ_MACOSX_PACKAGE_MANAGER']
1084
+ else 'macos-brew'
1085
+ end
1086
+ if !OS_PACKAGE_HANDLERS.include?(manager)
1087
+ known_managers = OS_PACKAGE_HANDLERS.keys.grep(/^macos/)
1088
+ raise ArgumentError, "#{manager} is not a known MacOSX package manager. Known package managers are #{known_managers.join(", ")}"
1089
+ end
1090
+
1091
+ managers =
1092
+ if manager == 'macos-port'
1093
+ [manager, 'port']
1094
+ else [manager]
1095
+ end
1096
+ [[*managers, 'darwin'], [version.strip]]
925
1097
  elsif Autobuild.windows?
926
1098
  [['windows'], []]
927
1099
  elsif File.exists?('/etc/SuSE-release')
@@ -1,3 +1,3 @@
1
1
  module Autoproj
2
- VERSION = "1.9.7.rc19"
2
+ VERSION = "1.9.7.rc20"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autoproj
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.7.rc19
4
+ version: 1.9.7.rc20
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-26 00:00:00.000000000 Z
12
+ date: 2014-05-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: autobuild