autoproj 1.9.7.rc19 → 1.9.7.rc20

Sign up to get free protection for your applications and to get access to all the features.
@@ -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