autoproj 1.4.4 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +15 -0
- data/Manifest.txt +5 -1
- data/README.txt +1 -41
- data/Rakefile +1 -1
- data/bin/autoproj +62 -747
- data/doc/guide/src/autoproj_bootstrap +54 -9
- data/doc/guide/src/customization.page +5 -4
- data/doc/guide/src/index.page +1 -41
- data/doc/guide/src/overview.png +0 -0
- data/doc/guide/src/overview.svg +537 -0
- data/doc/guide/src/package_sets/autobuild.page +37 -13
- data/doc/guide/src/package_sets/importers.page +1 -1
- data/doc/guide/src/package_sets/manifest-xml.page +2 -2
- data/doc/guide/src/package_sets/osdeps.page +14 -9
- data/doc/guide/src/quick_start.page +110 -0
- data/doc/guide/src/{structure.page → writing_manifest.page} +47 -57
- data/lib/autoproj.rb +1 -0
- data/lib/autoproj/autobuild.rb +74 -32
- data/lib/autoproj/cmdline.rb +912 -0
- data/lib/autoproj/default.osdeps +12 -2
- data/lib/autoproj/manifest.rb +141 -88
- data/lib/autoproj/osdeps.rb +42 -7
- data/lib/autoproj/version.rb +1 -1
- metadata +90 -53
data/lib/autoproj/default.osdeps
CHANGED
@@ -12,7 +12,17 @@ ruby18:
|
|
12
12
|
- dev-lang/ruby:1.8
|
13
13
|
|
14
14
|
ruby19:
|
15
|
-
debian
|
15
|
+
debian:
|
16
|
+
squeeze,sid:
|
17
|
+
- ruby1.9.1
|
18
|
+
- ruby1.9.1-dev
|
19
|
+
- rubygems1.9.1
|
20
|
+
stable:
|
21
|
+
- ruby1.9.1
|
22
|
+
- ruby1.9.1-dev
|
23
|
+
- rubygems1.9.1
|
24
|
+
|
25
|
+
ubuntu:
|
16
26
|
- ruby1.9.1
|
17
27
|
- ruby1.9.1-dev
|
18
28
|
- rubygems1.9.1
|
@@ -46,7 +56,7 @@ autoproj: gem
|
|
46
56
|
# The following definitions are for the VCS and build systems
|
47
57
|
git:
|
48
58
|
debian,ubuntu: git-core
|
49
|
-
gentoo: dev-
|
59
|
+
gentoo: dev-vcs/git
|
50
60
|
arch: git
|
51
61
|
svn:
|
52
62
|
debian,ubuntu: subversion
|
data/lib/autoproj/manifest.rb
CHANGED
@@ -3,18 +3,6 @@ require 'utilrb/kernel/options'
|
|
3
3
|
require 'nokogiri'
|
4
4
|
require 'set'
|
5
5
|
|
6
|
-
module Autobuild
|
7
|
-
class Package
|
8
|
-
def os_packages
|
9
|
-
@os_packages || Array.new
|
10
|
-
end
|
11
|
-
def depends_on_os_package(name)
|
12
|
-
@os_packages ||= Array.new
|
13
|
-
@os_packages << name
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
6
|
module Autoproj
|
19
7
|
@build_system_dependencies = Set.new
|
20
8
|
|
@@ -106,13 +94,22 @@ module Autoproj
|
|
106
94
|
@type == 'local'
|
107
95
|
end
|
108
96
|
|
97
|
+
def self.to_absolute_url(url, root_dir = nil)
|
98
|
+
# NOTE: we MUST use nil as default argument of root_dir as we don't
|
99
|
+
# want to call Autoproj.root_dir unless completely necessary
|
100
|
+
# (to_absolute_url might be called on installations that are being
|
101
|
+
# bootstrapped, and as such don't have a root dir yet).
|
102
|
+
url = Autoproj.single_expansion(url, 'HOME' => ENV['HOME'])
|
103
|
+
if url && url !~ /^(\w+:\/)?\/|^\w+\@|^(\w+\@)?[\w\.-]+:/
|
104
|
+
url = File.expand_path(url, root_dir || Autoproj.root_dir)
|
105
|
+
end
|
106
|
+
url
|
107
|
+
end
|
108
|
+
|
109
109
|
def create_autobuild_importer
|
110
110
|
return if type == "none"
|
111
111
|
|
112
|
-
url =
|
113
|
-
if url && url !~ /^(\w+:\/)?\/|^\w+\@|^(\w+\@)?[\w\.-]+:/
|
114
|
-
url = File.expand_path(url, Autoproj.root_dir)
|
115
|
-
end
|
112
|
+
url = VCSDefinition.to_absolute_url(self.url)
|
116
113
|
Autobuild.send(type, url, options)
|
117
114
|
end
|
118
115
|
|
@@ -196,26 +193,44 @@ module Autoproj
|
|
196
193
|
|
197
194
|
# True if this source has already been checked out on the local autoproj
|
198
195
|
# installation
|
199
|
-
def present?; File.directory?(
|
196
|
+
def present?; File.directory?(raw_local_dir) end
|
200
197
|
# True if this source is local, i.e. is not under a version control
|
201
198
|
def local?; vcs.local? end
|
202
199
|
# True if this source defines nothing
|
203
200
|
def empty?
|
204
201
|
!source_definition['version_control'] &&
|
205
202
|
!each_package.find { true } &&
|
206
|
-
!File.exists?(File.join(
|
207
|
-
!File.exists?(File.join(
|
203
|
+
!File.exists?(File.join(raw_local_dir, "overrides.rb")) &&
|
204
|
+
!File.exists?(File.join(raw_local_dir, "init.rb"))
|
208
205
|
end
|
209
206
|
|
210
|
-
|
211
|
-
def local_dir
|
207
|
+
def raw_local_dir
|
212
208
|
if local?
|
213
|
-
vcs.url
|
209
|
+
return vcs.url
|
214
210
|
else
|
215
211
|
File.join(Autoproj.remotes_dir, automatic_name)
|
216
212
|
end
|
217
213
|
end
|
218
214
|
|
215
|
+
def user_local_dir
|
216
|
+
if local?
|
217
|
+
return vcs.url
|
218
|
+
else
|
219
|
+
File.join(Autoproj.config_dir, 'remotes', name)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# The directory in which data for this source will be checked out
|
224
|
+
def local_dir
|
225
|
+
ugly_dir = raw_local_dir
|
226
|
+
pretty_dir = user_local_dir
|
227
|
+
if File.symlink?(pretty_dir) && File.readlink(pretty_dir) == ugly_dir
|
228
|
+
pretty_dir
|
229
|
+
else
|
230
|
+
ugly_dir
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
219
234
|
# A name generated from the VCS url
|
220
235
|
def automatic_name
|
221
236
|
vcs.to_s.gsub(/[^\w]/, '_')
|
@@ -237,7 +252,7 @@ module Autoproj
|
|
237
252
|
raise InternalError, "source #{vcs} has not been fetched yet, cannot load description for it"
|
238
253
|
end
|
239
254
|
|
240
|
-
source_file = File.join(
|
255
|
+
source_file = File.join(raw_local_dir, "source.yml")
|
241
256
|
if !File.exists?(source_file)
|
242
257
|
raise ConfigError, "source #{vcs.type}:#{vcs.url} should have a source.yml file, but does not"
|
243
258
|
end
|
@@ -255,21 +270,30 @@ module Autoproj
|
|
255
270
|
source_definition
|
256
271
|
end
|
257
272
|
|
273
|
+
# Load and validate the name from the YAML hash
|
258
274
|
def load_name
|
259
|
-
definition = raw_description_file
|
275
|
+
definition = @source_definition || raw_description_file
|
260
276
|
@name = definition['name']
|
261
|
-
|
277
|
+
|
278
|
+
if @name !~ /^[\w_\.-]+$/
|
279
|
+
raise ConfigError, "invalid source name '#{@name}': source names can only contain alphanumeric characters, and .-_"
|
280
|
+
elsif @name == "local"
|
262
281
|
raise ConfigError, "source #{self} is named 'local', but this is a reserved name"
|
263
282
|
end
|
264
283
|
|
265
284
|
rescue InternalError
|
266
285
|
end
|
267
286
|
|
287
|
+
def source_file
|
288
|
+
File.join(local_dir, 'source.yml')
|
289
|
+
end
|
290
|
+
|
268
291
|
# Load the source.yml file that describes this source, and resolve the
|
269
292
|
# $BLABLA values that are in there. Use #raw_description_file to avoid
|
270
293
|
# resolving those values
|
271
294
|
def load_description_file
|
272
295
|
@source_definition = raw_description_file
|
296
|
+
load_name
|
273
297
|
|
274
298
|
# Compute the definition of constants
|
275
299
|
begin
|
@@ -342,8 +366,12 @@ module Autoproj
|
|
342
366
|
urls['HOME'] = ENV['HOME']
|
343
367
|
|
344
368
|
all_vcs = source_definition['version_control']
|
345
|
-
if all_vcs
|
346
|
-
|
369
|
+
if all_vcs
|
370
|
+
if all_vcs.kind_of?(Hash)
|
371
|
+
raise ConfigError, "wrong format for the version_control field, you forgot the '-' in front of the package names"
|
372
|
+
elsif !all_vcs.kind_of?(Array)
|
373
|
+
raise ConfigError, "wrong format for the version_control field"
|
374
|
+
end
|
347
375
|
end
|
348
376
|
|
349
377
|
vcs_spec = Hash.new
|
@@ -412,7 +440,7 @@ module Autoproj
|
|
412
440
|
Autoproj.normalize_vcs_definition(vcs_spec)
|
413
441
|
end
|
414
442
|
rescue ConfigError => e
|
415
|
-
raise ConfigError, "#{e.message} in
|
443
|
+
raise ConfigError, "#{e.message} in #{source_file}", e.backtrace
|
416
444
|
end
|
417
445
|
|
418
446
|
def each_package
|
@@ -439,8 +467,12 @@ module Autoproj
|
|
439
467
|
def load_name
|
440
468
|
end
|
441
469
|
|
470
|
+
def source_file
|
471
|
+
File.join(Autoproj.config_dir, "overrides.yml")
|
472
|
+
end
|
473
|
+
|
442
474
|
def raw_description_file
|
443
|
-
path =
|
475
|
+
path = source_file
|
444
476
|
if File.file?(path)
|
445
477
|
begin
|
446
478
|
data = YAML.load(File.read(path)) || Hash.new
|
@@ -458,7 +490,7 @@ module Autoproj
|
|
458
490
|
PackageDefinition = Struct.new :autobuild, :user_block, :package_set, :file
|
459
491
|
|
460
492
|
class Manifest
|
461
|
-
FakePackage = Struct.new :text_name, :name, :srcdir, :importer
|
493
|
+
FakePackage = Struct.new :text_name, :name, :srcdir, :importer, :updated
|
462
494
|
class FakePackage
|
463
495
|
def autoproj_name; name end
|
464
496
|
def import
|
@@ -503,6 +535,10 @@ module Autoproj
|
|
503
535
|
|
504
536
|
attr_reader :file
|
505
537
|
|
538
|
+
def auto_update?
|
539
|
+
!!data['auto_update']
|
540
|
+
end
|
541
|
+
|
506
542
|
def initialize(file, data)
|
507
543
|
@file = file
|
508
544
|
@data = data
|
@@ -633,36 +669,26 @@ module Autoproj
|
|
633
669
|
return @sources.each(&block)
|
634
670
|
end
|
635
671
|
|
636
|
-
|
672
|
+
all_sources = []
|
673
|
+
|
674
|
+
(data['package_sets'] || []).each do |spec|
|
675
|
+
all_sources << source_from_spec(spec, load_description)
|
676
|
+
end
|
677
|
+
|
678
|
+
# Now load the local source
|
637
679
|
local = LocalSource.new
|
638
680
|
if load_description
|
639
681
|
local.load_description_file
|
640
682
|
else
|
641
683
|
local.load_name
|
642
684
|
end
|
643
|
-
if load_description
|
644
|
-
|
645
|
-
@sources = [local]
|
646
|
-
else
|
647
|
-
@sources = []
|
648
|
-
end
|
649
|
-
else
|
650
|
-
yield(local)
|
651
|
-
end
|
652
|
-
|
653
|
-
return if !data['package_sets']
|
654
|
-
|
655
|
-
data['package_sets'].each do |spec|
|
656
|
-
source = source_from_spec(spec, load_description)
|
657
|
-
if load_description
|
658
|
-
@sources << source
|
659
|
-
else
|
660
|
-
yield(source)
|
661
|
-
end
|
685
|
+
if !load_description || !local.empty?
|
686
|
+
all_sources << local
|
662
687
|
end
|
663
688
|
|
689
|
+
all_sources.each(&block)
|
664
690
|
if load_description
|
665
|
-
@sources
|
691
|
+
@sources = all_sources
|
666
692
|
end
|
667
693
|
end
|
668
694
|
|
@@ -704,6 +730,13 @@ module Autoproj
|
|
704
730
|
self
|
705
731
|
end
|
706
732
|
|
733
|
+
# Creates an autobuild package whose job is to allow the import of a
|
734
|
+
# specific repository into a given directory.
|
735
|
+
#
|
736
|
+
# +vcs+ is the VCSDefinition file describing the repository, +text_name+
|
737
|
+
# the name used when displaying the import progress, +pkg_name+ the
|
738
|
+
# internal name used to represent the package and +into+ the directory
|
739
|
+
# in which the package should be checked out.
|
707
740
|
def self.create_autobuild_package(vcs, text_name, pkg_name, into)
|
708
741
|
importer = vcs.create_autobuild_importer
|
709
742
|
return if !importer # updates have been disabled by using the 'none' type
|
@@ -716,6 +749,9 @@ module Autoproj
|
|
716
749
|
raise ConfigError, "cannot import #{name}: #{e.message}", e.backtrace
|
717
750
|
end
|
718
751
|
|
752
|
+
# Imports or updates a source (remote or otherwise).
|
753
|
+
#
|
754
|
+
# See create_autobuild_package for informations about the arguments.
|
719
755
|
def self.update_source(vcs, text_name, pkg_name, into)
|
720
756
|
fake_package = create_autobuild_package(vcs, text_name, pkg_name, into)
|
721
757
|
fake_package.import
|
@@ -724,15 +760,38 @@ module Autoproj
|
|
724
760
|
raise ConfigError, "cannot import #{name}: #{e.message}", e.backtrace
|
725
761
|
end
|
726
762
|
|
763
|
+
# Updates the main autoproj configuration
|
727
764
|
def update_yourself
|
728
765
|
Manifest.update_source(vcs, "autoproj main configuration", "autoproj_conf", Autoproj.config_dir)
|
729
766
|
end
|
730
767
|
|
768
|
+
# Updates all the remote sources in ROOT_DIR/.remotes, as well as the
|
769
|
+
# symbolic links in ROOT_DIR/autoproj/remotes
|
731
770
|
def update_remote_sources
|
732
771
|
# Iterate on the remote sources, without loading the source.yml
|
733
772
|
# file (we're not ready for that yet)
|
773
|
+
sources = []
|
734
774
|
each_remote_source(false) do |source|
|
735
|
-
Manifest.update_source(source.vcs, source.name || source.vcs.url, source.automatic_name, source.
|
775
|
+
Manifest.update_source(source.vcs, source.name || source.vcs.url, source.automatic_name, source.raw_local_dir)
|
776
|
+
sources << source
|
777
|
+
end
|
778
|
+
|
779
|
+
# Check for directories in ROOT_DIR/.remotes that do not map to a
|
780
|
+
# source repository, and remove them
|
781
|
+
Dir.glob(File.join(Autoproj.remotes_dir, '*')).each do |dir|
|
782
|
+
dir = File.expand_path(dir)
|
783
|
+
if File.directory?(dir) && !sources.any? { |s| s.raw_local_dir == dir }
|
784
|
+
FileUtils.rm_rf dir
|
785
|
+
end
|
786
|
+
end
|
787
|
+
|
788
|
+
remotes_symlinks_dir = File.join(Autoproj.config_dir, 'remotes')
|
789
|
+
FileUtils.rm_rf remotes_symlinks_dir
|
790
|
+
FileUtils.mkdir remotes_symlinks_dir
|
791
|
+
# Create symbolic links from .remotes/weird_url to
|
792
|
+
# autoproj/remotes/name
|
793
|
+
each_remote_source(false) do |source|
|
794
|
+
FileUtils.ln_sf source.raw_local_dir, File.join(remotes_symlinks_dir, source.name)
|
736
795
|
end
|
737
796
|
end
|
738
797
|
|
@@ -772,7 +831,8 @@ module Autoproj
|
|
772
831
|
# by S1
|
773
832
|
def load_importers
|
774
833
|
packages.each_value do |pkg|
|
775
|
-
vcs = importer_definition_for(pkg.autobuild.name, pkg.package_set)
|
834
|
+
vcs = importer_definition_for(pkg.autobuild.name, pkg.package_set) ||
|
835
|
+
importer_definition_for("default", pkg.package_set)
|
776
836
|
|
777
837
|
if vcs
|
778
838
|
Autoproj.add_build_system_dependency vcs.type
|
@@ -876,21 +936,6 @@ module Autoproj
|
|
876
936
|
yield
|
877
937
|
end
|
878
938
|
|
879
|
-
def handle_enabled_packages(selected_packages)
|
880
|
-
handled_packages = Set.new
|
881
|
-
each_package_set(selected_packages) do |name, packages, enabled_packages|
|
882
|
-
packages -= handled_packages
|
883
|
-
enabled_packages -= handled_packages
|
884
|
-
|
885
|
-
in_sublayout(name, packages) do
|
886
|
-
if !packages.empty?
|
887
|
-
yield(name, packages, enabled_packages)
|
888
|
-
end
|
889
|
-
end
|
890
|
-
handled_packages |= packages
|
891
|
-
end
|
892
|
-
end
|
893
|
-
|
894
939
|
def default_packages
|
895
940
|
names = if layout = data['layout']
|
896
941
|
layout_packages(layout, true)
|
@@ -925,10 +970,7 @@ module Autoproj
|
|
925
970
|
manifest = PackageManifest.load(package, manifest_path)
|
926
971
|
package_manifests[package.name] = manifest
|
927
972
|
|
928
|
-
manifest.
|
929
|
-
if Autoproj.verbose
|
930
|
-
STDERR.puts " #{package.name} depends on #{name}"
|
931
|
-
end
|
973
|
+
manifest.each_dependency do |name|
|
932
974
|
begin
|
933
975
|
package.depends_on name
|
934
976
|
rescue Autobuild::ConfigException => e
|
@@ -959,18 +1001,14 @@ module Autoproj
|
|
959
1001
|
required_os_packages = Set.new
|
960
1002
|
package_os_deps = Hash.new { |h, k| h[k] = Array.new }
|
961
1003
|
packages.each do |pkg_name|
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
required_os_packages << osdep_name
|
966
|
-
end
|
1004
|
+
pkg = Autobuild::Package[pkg_name]
|
1005
|
+
if !pkg
|
1006
|
+
raise InternalError, "internal error: #{pkg_name} is not a package"
|
967
1007
|
end
|
968
1008
|
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
required_os_packages << osdep_name
|
973
|
-
end
|
1009
|
+
pkg.os_packages.each do |osdep_name|
|
1010
|
+
package_os_deps[osdep_name] << pkg_name
|
1011
|
+
required_os_packages << osdep_name
|
974
1012
|
end
|
975
1013
|
end
|
976
1014
|
|
@@ -1020,11 +1058,12 @@ module Autoproj
|
|
1020
1058
|
if layout_name[0..-1] =~ Regexp.new("#{sel}\/?$")
|
1021
1059
|
expanded_packages.concat(packages.to_a)
|
1022
1060
|
else
|
1023
|
-
|
1024
|
-
|
1061
|
+
match = Regexp.new("^#{Regexp.quote(sel)}")
|
1062
|
+
Autobuild::Package.each(true) do |name, pkg|
|
1063
|
+
if pkg.srcdir =~ match
|
1064
|
+
expanded_packages << name
|
1065
|
+
end
|
1025
1066
|
end
|
1026
|
-
expanded_packages.concat(packages)
|
1027
|
-
!packages.empty?
|
1028
1067
|
end
|
1029
1068
|
end
|
1030
1069
|
end
|
@@ -1032,14 +1071,19 @@ module Autoproj
|
|
1032
1071
|
end
|
1033
1072
|
end
|
1034
1073
|
|
1035
|
-
# The singleton manifest object on which the current run works
|
1036
1074
|
class << self
|
1075
|
+
# The singleton manifest object on which the current run works
|
1037
1076
|
attr_accessor :manifest
|
1077
|
+
|
1078
|
+
# The operating system package definitions
|
1079
|
+
attr_accessor :osdeps
|
1038
1080
|
end
|
1039
1081
|
|
1040
1082
|
class PackageManifest
|
1041
1083
|
def self.load(package, file)
|
1042
|
-
doc = Nokogiri::XML(File.read(file))
|
1084
|
+
doc = Nokogiri::XML(File.read(file)) do |c|
|
1085
|
+
c.noblanks
|
1086
|
+
end
|
1043
1087
|
PackageManifest.new(package, doc)
|
1044
1088
|
end
|
1045
1089
|
|
@@ -1053,6 +1097,15 @@ module Autoproj
|
|
1053
1097
|
@xml = doc
|
1054
1098
|
end
|
1055
1099
|
|
1100
|
+
def each_dependency(&block)
|
1101
|
+
if block_given?
|
1102
|
+
each_os_dependency(&block)
|
1103
|
+
each_package_dependency(&block)
|
1104
|
+
else
|
1105
|
+
enum_for(:each_dependency, &block)
|
1106
|
+
end
|
1107
|
+
end
|
1108
|
+
|
1056
1109
|
def each_os_dependency
|
1057
1110
|
if block_given?
|
1058
1111
|
xml.xpath('//rosdep').each do |node|
|
data/lib/autoproj/osdeps.rb
CHANGED
@@ -2,12 +2,12 @@ require 'tempfile'
|
|
2
2
|
module Autoproj
|
3
3
|
class OSDependencies
|
4
4
|
def self.load(file)
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
begin
|
6
|
+
data = YAML.load(File.read(file))
|
7
|
+
verify_definitions(data)
|
8
|
+
rescue ArgumentError => e
|
9
|
+
raise ConfigError, "error in #{file}: #{e.message}"
|
10
|
+
end
|
11
11
|
|
12
12
|
OSDependencies.new(data)
|
13
13
|
end
|
@@ -47,6 +47,23 @@ module Autoproj
|
|
47
47
|
@definitions = definitions.merge(info.definitions)
|
48
48
|
end
|
49
49
|
|
50
|
+
def self.verify_definitions(hash = nil)
|
51
|
+
hash ||= definitions
|
52
|
+
hash.each do |key, value|
|
53
|
+
if !key.kind_of?(String)
|
54
|
+
raise ArgumentError, "invalid osdeps definition: found an #{key.class}. Don't forget to put quotes around numbers"
|
55
|
+
end
|
56
|
+
next if !value
|
57
|
+
if value.kind_of?(Array) || value.kind_of?(Hash)
|
58
|
+
verify_definitions(value)
|
59
|
+
else
|
60
|
+
if !value.kind_of?(String)
|
61
|
+
raise ArgumentError, "invalid osdeps definition: found an #{value.class}. Don't forget to put quotes around numbers"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
50
67
|
def operating_system
|
51
68
|
if @operating_system
|
52
69
|
return @operating_system
|
@@ -144,7 +161,9 @@ module Autoproj
|
|
144
161
|
version_entry = data.find do |version_list, data|
|
145
162
|
version_list.to_s.split(',').
|
146
163
|
map(&:downcase).
|
147
|
-
any?
|
164
|
+
any? do |v|
|
165
|
+
os_version.any? { |osv| Regexp.new(v) =~ osv }
|
166
|
+
end
|
148
167
|
end
|
149
168
|
|
150
169
|
if !version_entry
|
@@ -168,8 +187,24 @@ module Autoproj
|
|
168
187
|
"\n" + shell_snippets
|
169
188
|
end
|
170
189
|
|
190
|
+
# Returns true if there is an operating-system package with that name,
|
191
|
+
# and false otherwise
|
192
|
+
def has?(name)
|
193
|
+
partition_packages([name].to_set)
|
194
|
+
true
|
195
|
+
rescue ConfigError
|
196
|
+
false
|
197
|
+
end
|
198
|
+
|
171
199
|
# call-seq:
|
172
200
|
# partition_packages(package_names) => os_packages, gem_packages
|
201
|
+
#
|
202
|
+
# Resolves the package names listed in +package_set+, and returns a set
|
203
|
+
# of packages that have to be installed using the platform's native
|
204
|
+
# package manager, and the set of packages that have to be installed
|
205
|
+
# using Ruby's package manager, RubyGems.
|
206
|
+
#
|
207
|
+
# Raises ConfigError if no package can be found
|
173
208
|
def partition_packages(package_set, package_osdeps = Hash.new)
|
174
209
|
package_set = package_set.
|
175
210
|
map { |name| OSDependencies.aliases[name] || name }.
|