autoproj 2.0.0.rc37 → 2.0.0.rc38
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -2
- data/Rakefile +1 -1
- data/bin/autoproj_bootstrap +34 -2
- data/bin/autoproj_bootstrap.in +4 -2
- data/bin/autoproj_install +34 -2
- data/bin/autoproj_install.in +4 -2
- data/lib/autoproj.rb +9 -2
- data/lib/autoproj/autobuild.rb +13 -742
- data/lib/autoproj/autobuild_extensions/archive_importer.rb +44 -0
- data/lib/autoproj/autobuild_extensions/dsl.rb +439 -0
- data/lib/autoproj/autobuild_extensions/git.rb +116 -0
- data/lib/autoproj/autobuild_extensions/package.rb +159 -0
- data/lib/autoproj/autobuild_extensions/svn.rb +11 -0
- data/lib/autoproj/cli/base.rb +17 -18
- data/lib/autoproj/cli/clean.rb +1 -2
- data/lib/autoproj/cli/envsh.rb +1 -2
- data/lib/autoproj/cli/inspection_tool.rb +12 -21
- data/lib/autoproj/cli/locate.rb +130 -73
- data/lib/autoproj/cli/main.rb +31 -5
- data/lib/autoproj/cli/main_plugin.rb +79 -0
- data/lib/autoproj/cli/main_test.rb +19 -5
- data/lib/autoproj/cli/osdeps.rb +1 -2
- data/lib/autoproj/cli/patcher.rb +21 -0
- data/lib/autoproj/cli/query.rb +34 -41
- data/lib/autoproj/cli/show.rb +121 -52
- data/lib/autoproj/cli/status.rb +4 -5
- data/lib/autoproj/cli/tag.rb +1 -1
- data/lib/autoproj/cli/test.rb +7 -6
- data/lib/autoproj/cli/update.rb +8 -22
- data/lib/autoproj/cli/versions.rb +1 -2
- data/lib/autoproj/configuration.rb +1 -1
- data/lib/autoproj/environment.rb +2 -7
- data/lib/autoproj/exceptions.rb +10 -8
- data/lib/autoproj/find_workspace.rb +46 -12
- data/lib/autoproj/installation_manifest.rb +34 -25
- data/lib/autoproj/local_package_set.rb +86 -0
- data/lib/autoproj/manifest.rb +448 -503
- data/lib/autoproj/metapackage.rb +31 -5
- data/lib/autoproj/ops/configuration.rb +46 -45
- data/lib/autoproj/ops/import.rb +150 -60
- data/lib/autoproj/ops/install.rb +25 -1
- data/lib/autoproj/ops/loader.rb +4 -1
- data/lib/autoproj/ops/main_config_switcher.rb +4 -4
- data/lib/autoproj/ops/snapshot.rb +4 -3
- data/lib/autoproj/os_package_installer.rb +105 -46
- data/lib/autoproj/os_package_resolver.rb +63 -36
- data/lib/autoproj/package_definition.rb +1 -0
- data/lib/autoproj/package_managers/apt_dpkg_manager.rb +30 -27
- data/lib/autoproj/package_managers/bundler_manager.rb +64 -18
- data/lib/autoproj/package_managers/gem_manager.rb +4 -2
- data/lib/autoproj/package_managers/manager.rb +26 -7
- data/lib/autoproj/package_managers/shell_script_manager.rb +4 -4
- data/lib/autoproj/package_managers/zypper_manager.rb +1 -1
- data/lib/autoproj/package_manifest.rb +154 -137
- data/lib/autoproj/package_selection.rb +16 -2
- data/lib/autoproj/package_set.rb +352 -309
- data/lib/autoproj/query.rb +13 -1
- data/lib/autoproj/system.rb +2 -2
- data/lib/autoproj/test.rb +164 -11
- data/lib/autoproj/variable_expansion.rb +15 -42
- data/lib/autoproj/vcs_definition.rb +93 -76
- data/lib/autoproj/version.rb +1 -1
- data/lib/autoproj/workspace.rb +116 -80
- metadata +10 -2
@@ -31,8 +31,7 @@ def run(user_selection, options)
|
|
31
31
|
initialize_and_load
|
32
32
|
packages, *, config_selected =
|
33
33
|
finalize_setup(user_selection,
|
34
|
-
recursive: options[:deps]
|
35
|
-
ignore_non_imported_packages: true)
|
34
|
+
recursive: options[:deps])
|
36
35
|
|
37
36
|
ops = Ops::Snapshot.new(ws.manifest, ignore_errors: options[:keep_going])
|
38
37
|
|
@@ -115,7 +115,7 @@ def validated_values
|
|
115
115
|
# should be converted to lowercase before it gets validated / saved.
|
116
116
|
# @option options [Boolean] :uppercase (false) whether the user's input
|
117
117
|
# should be converted to uppercase before it gets validated / saved.
|
118
|
-
def declare(name, type, options, &validator)
|
118
|
+
def declare(name, type, **options, &validator)
|
119
119
|
declared_options[name] = BuildOption.new(name, type, options, validator)
|
120
120
|
end
|
121
121
|
|
data/lib/autoproj/environment.rb
CHANGED
@@ -8,18 +8,13 @@ class Environment < Autobuild::Environment
|
|
8
8
|
attr_reader :root_dir
|
9
9
|
|
10
10
|
def prepare(root_dir)
|
11
|
-
super()
|
12
|
-
|
13
11
|
@root_dir = root_dir
|
14
12
|
set 'AUTOPROJ_CURRENT_ROOT', root_dir
|
13
|
+
super()
|
15
14
|
end
|
16
15
|
|
17
16
|
def filter_original_env(name, env)
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
def expand(value)
|
22
|
-
Autoproj.expand_environment(value)
|
17
|
+
Autoproj.filter_out_paths_in_workspace(env)
|
23
18
|
end
|
24
19
|
|
25
20
|
def export_env_sh(subdir = nil, options = Hash.new)
|
data/lib/autoproj/exceptions.rb
CHANGED
@@ -12,6 +12,11 @@ class InternalError < RuntimeError; end
|
|
12
12
|
class PackageNotFound < ConfigError
|
13
13
|
end
|
14
14
|
|
15
|
+
class UnregisteredPackage < ArgumentError
|
16
|
+
end
|
17
|
+
|
18
|
+
class InvalidPackageManifest < RuntimeError; end
|
19
|
+
|
15
20
|
class InputError < RuntimeError; end
|
16
21
|
|
17
22
|
# Exception raised when a caller requires to use an excluded package
|
@@ -22,16 +27,13 @@ def initialize(name)
|
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
25
|
-
# Exception raised when an unknown package is encountered
|
26
|
-
class UnknownPackage < ConfigError
|
27
|
-
attr_reader :name
|
28
|
-
def initialize(name)
|
29
|
-
@name = name
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
30
|
class MissingOSDep < ConfigError; end
|
34
31
|
|
32
|
+
# Exception raised when finding unexpected objects in a YAML file
|
33
|
+
#
|
34
|
+
# E.g. having a hash instead of an array
|
35
|
+
class InvalidYAMLFormatting < ConfigError; end
|
36
|
+
|
35
37
|
# Exception raised by
|
36
38
|
# PackageSelection#filter_excluded_and_ignored_packages when a given
|
37
39
|
# selection is completely excluded
|
@@ -21,19 +21,13 @@ def self.find_prefix_dir(base_dir = default_find_base_dir)
|
|
21
21
|
find_v2_prefix_dir(base_dir)
|
22
22
|
end
|
23
23
|
|
24
|
-
#
|
25
|
-
#
|
26
|
-
# Finds an autoproj "root directory" that contains a given directory. It
|
27
|
-
# can either be the root of a workspace or the root of an install
|
24
|
+
# Find a workspace configuration file in the parent tree of a given
|
28
25
|
# directory
|
29
26
|
#
|
30
|
-
# @param [String] base_dir the
|
31
|
-
# @
|
32
|
-
#
|
33
|
-
|
34
|
-
# @return [String,nil] the root of the workspace directory, or nil if
|
35
|
-
# there's none
|
36
|
-
def self.find_v2_root_dir(base_dir, config_field_name)
|
27
|
+
# @param [String] base_dir the directory to start from
|
28
|
+
# @return [(String,Hash),nil] the root path, and the configuration, or nil
|
29
|
+
# if base_dir is not part of a workspace
|
30
|
+
def self.find_v2_workspace_config(base_dir)
|
37
31
|
path = Pathname.new(base_dir).expand_path
|
38
32
|
while !path.root?
|
39
33
|
if (path + ".autoproj" + "config.yml").exist?
|
@@ -47,8 +41,24 @@ def self.find_v2_root_dir(base_dir, config_field_name)
|
|
47
41
|
end
|
48
42
|
|
49
43
|
config_path = path + ".autoproj" + "config.yml"
|
44
|
+
return path.to_s, (YAML.load(config_path.read) || Hash.new)
|
45
|
+
end
|
50
46
|
|
51
|
-
|
47
|
+
# @private
|
48
|
+
#
|
49
|
+
# Finds an autoproj "root directory" that contains a given directory. It
|
50
|
+
# can either be the root of a workspace or the root of an install
|
51
|
+
# directory
|
52
|
+
#
|
53
|
+
# @param [String] base_dir the start of the search
|
54
|
+
# @param [String] config_field_name the name of a field in the root's
|
55
|
+
# configuration file, that should be returned instead of the root
|
56
|
+
# itself
|
57
|
+
# @return [String,nil] the root of the workspace directory, or nil if
|
58
|
+
# there's none
|
59
|
+
def self.find_v2_root_dir(base_dir, config_field_name)
|
60
|
+
path, config = find_v2_workspace_config(base_dir)
|
61
|
+
return if !path
|
52
62
|
result = config[config_field_name] || path.to_s
|
53
63
|
result = File.expand_path(result, path.to_s)
|
54
64
|
if result == path.to_s
|
@@ -62,6 +72,30 @@ def self.find_v2_root_dir(base_dir, config_field_name)
|
|
62
72
|
resolved
|
63
73
|
end
|
64
74
|
|
75
|
+
# Filters in the given list of paths the paths that are within a workspace
|
76
|
+
def self.filter_out_paths_in_workspace(paths)
|
77
|
+
known_valid_dirs = Set.new
|
78
|
+
known_workspace_dirs = Array.new
|
79
|
+
paths.find_all do |p|
|
80
|
+
if !File.directory?(p)
|
81
|
+
true
|
82
|
+
elsif known_workspace_dirs.any? { |ws_root| "#{p}/".start_with?(ws_root) }
|
83
|
+
false
|
84
|
+
else
|
85
|
+
ws_path, ws_config = find_v2_workspace_config(p)
|
86
|
+
if ws_path
|
87
|
+
known_workspace_dirs << "#{ws_path}/"
|
88
|
+
if ws_dir = ws_config['workspace']
|
89
|
+
known_workspace_dirs << "#{ws_dir}/"
|
90
|
+
end
|
91
|
+
false
|
92
|
+
else
|
93
|
+
true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
65
99
|
# {#find_workspace_dir} for v2 workspaces
|
66
100
|
def self.find_v2_workspace_dir(base_dir = default_find_base_dir)
|
67
101
|
find_v2_root_dir(base_dir, 'workspace')
|
@@ -2,31 +2,35 @@ module Autoproj
|
|
2
2
|
# Manifest of installed packages imported from another autoproj installation
|
3
3
|
class InstallationManifest
|
4
4
|
Package = Struct.new :name, :srcdir, :prefix, :builddir, :dependencies
|
5
|
+
PackageSet = Struct.new :name, :raw_local_dir, :user_local_dir
|
5
6
|
|
6
7
|
attr_reader :path
|
7
8
|
attr_reader :packages
|
9
|
+
attr_reader :package_sets
|
8
10
|
def initialize(path)
|
9
11
|
@path = path
|
10
12
|
@packages = Hash.new
|
13
|
+
@package_sets = Hash.new
|
11
14
|
end
|
12
15
|
|
13
16
|
def exist?
|
14
17
|
File.exist?(path)
|
15
18
|
end
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
# @return [Package]
|
20
|
-
def [](name)
|
21
|
-
packages[name]
|
20
|
+
def add_package(pkg)
|
21
|
+
packages[pkg.name] = pkg
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
|
24
|
+
def add_package_set(pkg_set)
|
25
|
+
package_sets[pkg_set.name] = pkg_set
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
|
28
|
+
def each_package_set(&block)
|
29
|
+
package_sets.each_value(&block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def each_package(&block)
|
33
|
+
packages.each_value(&block)
|
30
34
|
end
|
31
35
|
|
32
36
|
def load
|
@@ -41,10 +45,16 @@ def load
|
|
41
45
|
save(path)
|
42
46
|
else
|
43
47
|
raw.each do |entry|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
if entry['package_set']
|
49
|
+
pkg_set = PackageSet.new(
|
50
|
+
entry['package_set'], entry['raw_local_dir'], entry['user_local_dir'])
|
51
|
+
package_sets[pkg_set.name] = pkg_set
|
52
|
+
else
|
53
|
+
pkg = Package.new(
|
54
|
+
entry['name'], entry['srcdir'], entry['prefix'],
|
55
|
+
entry['builddir'], entry['dependencies'])
|
56
|
+
packages[pkg.name] = pkg
|
57
|
+
end
|
48
58
|
end
|
49
59
|
end
|
50
60
|
end
|
@@ -52,35 +62,34 @@ def load
|
|
52
62
|
# Save the installation manifest
|
53
63
|
def save(path = self.path)
|
54
64
|
File.open(path, 'w') do |io|
|
55
|
-
|
65
|
+
marshalled_package_sets = each_package_set.map do |v|
|
66
|
+
Hash['package_set' => v.name,
|
67
|
+
'raw_local_dir' => v.raw_local_dir,
|
68
|
+
'user_local_dir' => v.user_local_dir]
|
69
|
+
end
|
70
|
+
marshalled_packages = each_package.map do |v|
|
71
|
+
v = v.autobuild
|
56
72
|
Hash['name' => v.name,
|
57
73
|
'srcdir' => v.srcdir,
|
58
74
|
'builddir' => (v.builddir if v.respond_to?(:builddir)),
|
59
75
|
'prefix' => v.prefix,
|
60
76
|
'dependencies' => v.dependencies]
|
61
77
|
end
|
62
|
-
YAML.dump(marshalled_packages, io)
|
78
|
+
YAML.dump(marshalled_package_sets + marshalled_packages, io)
|
63
79
|
end
|
64
80
|
end
|
65
81
|
|
66
|
-
# Enumerate the packages from this manifest
|
67
|
-
#
|
68
|
-
# @yieldparam [Package]
|
69
|
-
def each(&block)
|
70
|
-
packages.each_value(&block)
|
71
|
-
end
|
72
|
-
|
73
82
|
# Returns the default Autoproj installation manifest path for a given
|
74
83
|
# autoproj workspace root
|
75
84
|
#
|
76
85
|
# @param [String] root_dir
|
77
86
|
# @return [String]
|
78
|
-
def self.
|
87
|
+
def self.path_for_workspace_root(root_dir)
|
79
88
|
File.join(root_dir, '.autoproj', 'installation-manifest')
|
80
89
|
end
|
81
90
|
|
82
|
-
def self.
|
83
|
-
path =
|
91
|
+
def self.from_workspace_root(root_dir)
|
92
|
+
path = path_for_workspace_root(root_dir)
|
84
93
|
manifest = InstallationManifest.new(path)
|
85
94
|
if !manifest.exist?
|
86
95
|
raise ConfigError.new, "no #{path} file found. You should probably rerun autoproj envsh in that folder first"
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Autoproj
|
2
|
+
# Specialization of the PackageSet class to handle the "master" package set
|
3
|
+
# in autoproj/
|
4
|
+
class LocalPackageSet < PackageSet
|
5
|
+
def initialize(ws, local_dir: ws.config_dir)
|
6
|
+
super(ws, VCSDefinition.none, name: 'main configuration', raw_local_dir: local_dir)
|
7
|
+
@local_dir = local_dir
|
8
|
+
end
|
9
|
+
|
10
|
+
def vcs
|
11
|
+
ws.manifest.vcs
|
12
|
+
end
|
13
|
+
|
14
|
+
def main?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def local?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
def local_dir
|
23
|
+
raw_local_dir
|
24
|
+
end
|
25
|
+
|
26
|
+
def manifest_path
|
27
|
+
manifest.file
|
28
|
+
end
|
29
|
+
|
30
|
+
def overrides_file_path
|
31
|
+
if d = local_dir
|
32
|
+
File.join(d, "overrides.yml")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def source_file
|
37
|
+
overrides_file_path
|
38
|
+
end
|
39
|
+
|
40
|
+
# Reimplemented from {PackageSet#load_description_file} to remove the
|
41
|
+
# name validation
|
42
|
+
def load_description_file
|
43
|
+
source_definition = raw_description_file
|
44
|
+
parse_source_definition(source_definition)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Load the files in overrides.d in addition to the overrides: field in
|
48
|
+
# the yaml file
|
49
|
+
def load_overrides(source_definition)
|
50
|
+
files = Dir.glob(File.join( ws.overrides_dir, "*.yml" ) ).sort
|
51
|
+
overrides = files.map do |file|
|
52
|
+
source_data = Autoproj.in_file(file, Autoproj::YAML_LOAD_ERROR) do
|
53
|
+
YAML.load(File.read(file)) || Array.new
|
54
|
+
end
|
55
|
+
source_data =
|
56
|
+
if source_data.respond_to?(:to_ary)
|
57
|
+
source_data
|
58
|
+
else source_data['overrides'] || Hash.new
|
59
|
+
end
|
60
|
+
[file, source_data]
|
61
|
+
end
|
62
|
+
overrides + super
|
63
|
+
end
|
64
|
+
|
65
|
+
def raw_description_file
|
66
|
+
description = Hash[
|
67
|
+
'imports' => Array.new,
|
68
|
+
'version_control' => Array.new,
|
69
|
+
'overrides' => Array.new]
|
70
|
+
if File.file?(overrides_file_path)
|
71
|
+
overrides_data = Autoproj.in_file(overrides_file_path, Autoproj::YAML_LOAD_ERROR) do
|
72
|
+
YAML.load(File.read(overrides_file_path)) || Hash.new
|
73
|
+
end
|
74
|
+
description = description.merge(overrides_data)
|
75
|
+
end
|
76
|
+
|
77
|
+
manifest_data = Autoproj.in_file(manifest_path, Autoproj::YAML_LOAD_ERROR) do
|
78
|
+
YAML.load(File.read(manifest_path)) || Hash.new
|
79
|
+
end
|
80
|
+
description['imports'] = description['imports'].
|
81
|
+
concat(manifest_data['package_sets'] || Array.new)
|
82
|
+
description['name'] = name
|
83
|
+
description
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/autoproj/manifest.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
require 'csv'
|
3
3
|
require 'utilrb/kernel/options'
|
4
4
|
require 'set'
|
5
|
-
require 'rexml/document'
|
6
5
|
|
7
6
|
require 'win32/dir' if RbConfig::CONFIG["host_os"] =~%r!(msdos|mswin|djgpp|mingw|[Ww]indows)!
|
8
7
|
|
@@ -26,6 +25,29 @@ def self.load(file)
|
|
26
25
|
manifest
|
27
26
|
end
|
28
27
|
|
28
|
+
# A normalized version of the layout as represented in the manifest file
|
29
|
+
#
|
30
|
+
# It is a mapping from a selection name into the layout level it is
|
31
|
+
# defined in. For instance:
|
32
|
+
#
|
33
|
+
# layout:
|
34
|
+
# - subdir:
|
35
|
+
# - pkg/in/subdir
|
36
|
+
# - pkg/in/root
|
37
|
+
#
|
38
|
+
# Would be normalized as
|
39
|
+
#
|
40
|
+
# 'pkg/in/subdir' => '/subdir/',
|
41
|
+
# 'pkg/in/root' => '/'
|
42
|
+
#
|
43
|
+
# Note that these are only strings. There is no normalization against
|
44
|
+
# package names or metapackages.
|
45
|
+
#
|
46
|
+
# This is computed by {#compute_normalized_layout}
|
47
|
+
#
|
48
|
+
# @return [Hash]
|
49
|
+
attr_reader :normalized_layout
|
50
|
+
|
29
51
|
# Load the manifest data contained in +file+
|
30
52
|
def load(file)
|
31
53
|
if !File.exist?(file)
|
@@ -37,21 +59,76 @@ def load(file)
|
|
37
59
|
end
|
38
60
|
|
39
61
|
@file = file
|
62
|
+
initialize_from_hash(data)
|
63
|
+
end
|
64
|
+
|
65
|
+
# @api private
|
66
|
+
#
|
67
|
+
# Initialize the manifest from a hash, as loaded from a manifest file
|
68
|
+
def initialize_from_hash(data)
|
40
69
|
@data = data
|
41
70
|
@ignored_packages |= (data['ignored_packages'] || Set.new).to_set
|
71
|
+
@ignored_packages |= (data['ignore_packages'] || Set.new).to_set
|
72
|
+
invalidate_ignored_package_names
|
42
73
|
@manifest_exclusions |= (data['exclude_packages'] || Set.new).to_set
|
43
74
|
|
44
|
-
|
75
|
+
normalized_layout = Hash.new
|
45
76
|
compute_normalized_layout(
|
46
77
|
normalized_layout,
|
47
78
|
'/',
|
48
79
|
data['layout'] || Hash.new)
|
80
|
+
@normalized_layout = normalized_layout
|
81
|
+
@has_layout = !!data['layout']
|
49
82
|
|
50
83
|
if data['constants']
|
51
84
|
@constant_definitions = Autoproj.resolve_constant_definitions(data['constants'])
|
52
85
|
end
|
53
86
|
end
|
54
87
|
|
88
|
+
# Make an empty layout
|
89
|
+
#
|
90
|
+
# Unless the default layout (that you can get with {#remove_layout}), this
|
91
|
+
# means that no package is selected by default
|
92
|
+
def clear_layout
|
93
|
+
@has_layout = true
|
94
|
+
normalized_layout.clear
|
95
|
+
end
|
96
|
+
|
97
|
+
# Remove the layout
|
98
|
+
#
|
99
|
+
# Unlike {#clear_layout}, this means that all defined source packages
|
100
|
+
# will be selected by default
|
101
|
+
def remove_layout
|
102
|
+
@has_layout = false
|
103
|
+
normalized_layout.clear
|
104
|
+
end
|
105
|
+
|
106
|
+
# Add a package into the layout
|
107
|
+
def add_package_to_layout(package)
|
108
|
+
package_name = validate_package_name_argument(package)
|
109
|
+
@has_layout = true
|
110
|
+
normalized_layout[package_name] = '/'
|
111
|
+
end
|
112
|
+
|
113
|
+
# Add a package into the layout
|
114
|
+
def add_package_set_to_layout(package_set)
|
115
|
+
validate_package_set_in_self(package_set)
|
116
|
+
add_metapackage_to_layout(package_set.metapackage)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Add a metapackage into the layout
|
120
|
+
def add_metapackage_to_layout(metapackage)
|
121
|
+
validate_metapackage_in_self(metapackage)
|
122
|
+
@has_layout = true
|
123
|
+
normalized_layout[metapackage.name] = '/'
|
124
|
+
end
|
125
|
+
|
126
|
+
# Add a constant definition, used when resolving $CONSTANT in loaded
|
127
|
+
# files
|
128
|
+
def add_constant_definition(key, value)
|
129
|
+
constant_definitions[key] = value
|
130
|
+
end
|
131
|
+
|
55
132
|
# The manifest data as a Hash
|
56
133
|
attr_reader :data
|
57
134
|
|
@@ -59,9 +136,6 @@ def load(file)
|
|
59
136
|
# [Autobuild::Package, package_set, file] tuple
|
60
137
|
attr_reader :packages
|
61
138
|
|
62
|
-
# A mapping from package names into PackageManifest objects
|
63
|
-
attr_reader :package_manifests
|
64
|
-
|
65
139
|
# The path to the manifest file that has been loaded
|
66
140
|
attr_reader :file
|
67
141
|
|
@@ -80,15 +154,6 @@ def accept_unavailable_osdeps?; !!@accept_unavailable_osdeps end
|
|
80
154
|
# Sets {#accept_unavailable_osdeps?}
|
81
155
|
def accept_unavailable_osdeps=(flag); @accept_unavailable_osdeps = flag end
|
82
156
|
|
83
|
-
# True if osdeps should be handled in update and build, or left to the
|
84
|
-
# osdeps command
|
85
|
-
def auto_osdeps?
|
86
|
-
if data.has_key?('auto_osdeps')
|
87
|
-
!!data['auto_osdeps']
|
88
|
-
else true
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
157
|
attr_reader :constant_definitions
|
93
158
|
|
94
159
|
attr_reader :metapackages
|
@@ -101,17 +166,24 @@ def auto_osdeps?
|
|
101
166
|
# The definition of all OS packages available on this installation
|
102
167
|
attr_reader :os_package_resolver
|
103
168
|
|
104
|
-
|
169
|
+
# Whether there is a layout specified
|
170
|
+
#
|
171
|
+
# This is used to disambiguate between an empty layout (which would
|
172
|
+
# build nothing) and no layout at all
|
173
|
+
attr_predicate :has_layout?
|
174
|
+
|
175
|
+
def initialize(ws, os_package_resolver: OSPackageResolver.new)
|
176
|
+
@ws = ws
|
105
177
|
@file = nil
|
106
178
|
@data = Hash.new
|
179
|
+
@has_layout = false
|
180
|
+
@normalized_layout = Hash.new
|
107
181
|
@packages = Hash.new
|
108
|
-
@package_manifests = Hash.new
|
109
182
|
@package_sets = []
|
110
|
-
@os_package_resolver =
|
183
|
+
@os_package_resolver = os_package_resolver
|
111
184
|
|
112
185
|
@automatic_exclusions = Hash.new
|
113
186
|
@constants_definitions = Hash.new
|
114
|
-
@disabled_imports = Set.new
|
115
187
|
@moved_packages = Hash.new
|
116
188
|
@osdeps_overrides = Hash.new
|
117
189
|
@metapackages = Hash.new
|
@@ -122,75 +194,172 @@ def initialize
|
|
122
194
|
@accept_unavailable_osdeps = false
|
123
195
|
|
124
196
|
@constant_definitions = Hash.new
|
125
|
-
@package_sets << LocalPackageSet.new(
|
197
|
+
@package_sets << LocalPackageSet.new(ws)
|
126
198
|
end
|
127
199
|
|
200
|
+
# @api private
|
201
|
+
#
|
202
|
+
# Validate that the given metapackage object is defined in self
|
203
|
+
def validate_metapackage_in_self(metapackage)
|
204
|
+
if find_metapackage(metapackage.name) != metapackage
|
205
|
+
raise UnregisteredPackage, "#{metapackage.name} is not registered on #{self}"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# @api private
|
210
|
+
#
|
211
|
+
# Validate that the given package object is defined in self
|
212
|
+
def validate_package_in_self(package)
|
213
|
+
if !package.respond_to?(:autobuild)
|
214
|
+
raise ArgumentError, "expected a PackageDefinition object but got an Autobuild package"
|
215
|
+
elsif find_package_definition(package.name) != package
|
216
|
+
raise UnregisteredPackage, "#{package.name} is not registered on #{self}"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# @api private
|
221
|
+
#
|
222
|
+
# Massage an argument that should be interpreted as a package name
|
223
|
+
def validate_package_name_argument(package, require_existing: true)
|
224
|
+
if package.respond_to?(:name)
|
225
|
+
validate_package_in_self(package)
|
226
|
+
package.name
|
227
|
+
else
|
228
|
+
package = package.to_str
|
229
|
+
if require_existing && !has_package?(package)
|
230
|
+
raise PackageNotFound, "no package named #{package} in #{self}"
|
231
|
+
end
|
232
|
+
package
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# @api private
|
237
|
+
#
|
238
|
+
# Validate that the given package object is defined in self
|
239
|
+
def validate_package_set_in_self(package_set)
|
240
|
+
if find_package_set(package.name) != package_set
|
241
|
+
raise UnregisteredPackageSet, "#{package_set.name} is not registered on #{self}"
|
242
|
+
end
|
243
|
+
end
|
128
244
|
|
129
245
|
# Call this method to ignore a specific package. It must not be used in
|
130
246
|
# init.rb, as the manifest is not yet loaded then
|
131
|
-
def ignore_package(
|
132
|
-
|
247
|
+
def ignore_package(package)
|
248
|
+
invalidate_ignored_package_names
|
249
|
+
@ignored_packages << validate_package_name_argument(package, require_existing: false)
|
133
250
|
end
|
134
251
|
|
135
252
|
# True if the given package should not be built, with the packages that
|
136
253
|
# depend on him have this dependency met.
|
137
254
|
#
|
138
255
|
# This is useful if the packages are already installed on this system.
|
139
|
-
def ignored?(
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
256
|
+
def ignored?(package)
|
257
|
+
package_name = validate_package_name_argument(package)
|
258
|
+
cache_ignored_package_names.include?(package_name)
|
259
|
+
end
|
260
|
+
|
261
|
+
# @api private
|
262
|
+
#
|
263
|
+
# The list of packages that are ignored
|
264
|
+
#
|
265
|
+
# Do not use directly, use {#ignored?} instead
|
266
|
+
def cache_ignored_package_names
|
267
|
+
if @ignored_package_names
|
268
|
+
return @ignored_package_names
|
148
269
|
end
|
270
|
+
|
271
|
+
@ignored_package_names = each_package_definition.find_all do |pkg|
|
272
|
+
ignored_packages.any? do |l|
|
273
|
+
(pkg.name == l) ||
|
274
|
+
((pkg_set = metapackages[l]) && pkg_set.include?(pkg))
|
275
|
+
end
|
276
|
+
end.map(&:name).to_set
|
277
|
+
end
|
278
|
+
|
279
|
+
# @api private
|
280
|
+
#
|
281
|
+
# Invalidate the cache computed by {#cache_ignored_package_names}
|
282
|
+
def invalidate_ignored_package_names
|
283
|
+
@ignored_package_names = nil
|
149
284
|
end
|
150
285
|
|
151
286
|
# Enumerates the package names of all ignored packages
|
152
|
-
|
153
|
-
|
154
|
-
|
287
|
+
#
|
288
|
+
# @yieldparam [Autobuild::Package]
|
289
|
+
def each_ignored_package
|
290
|
+
return enum_for(__method__) if !block_given?
|
291
|
+
cache_ignored_package_names.each do |pkg_name|
|
292
|
+
yield(find_autobuild_package(pkg_name))
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# Removes all registered ignored packages
|
297
|
+
def clear_ignored
|
298
|
+
invalidate_ignored_package_names
|
299
|
+
ignored_packages.clear
|
300
|
+
end
|
301
|
+
|
302
|
+
# True if the given package should not be built and its dependencies
|
303
|
+
# should be considered as met.
|
304
|
+
#
|
305
|
+
# This is useful to avoid building packages that are of no use for the
|
306
|
+
# user.
|
307
|
+
def excluded?(package_name)
|
308
|
+
package_name = validate_package_name_argument(package_name)
|
309
|
+
|
310
|
+
if excluded_in_manifest?(package_name)
|
311
|
+
true
|
312
|
+
elsif automatic_exclusions.any? { |pkg_name, | pkg_name == package_name }
|
313
|
+
true
|
314
|
+
else
|
315
|
+
false
|
155
316
|
end
|
156
317
|
end
|
157
318
|
|
158
319
|
# Enumerates the package names of all ignored packages
|
159
|
-
def
|
320
|
+
def each_excluded_package
|
321
|
+
return enum_for(__method__) if !block_given?
|
160
322
|
each_autobuild_package do |pkg|
|
161
|
-
yield(pkg) if
|
323
|
+
yield(pkg) if excluded?(pkg.name)
|
162
324
|
end
|
163
325
|
end
|
164
326
|
|
165
327
|
# Removes all registered exclusions
|
166
328
|
def clear_exclusions
|
167
329
|
automatic_exclusions.clear
|
168
|
-
|
169
|
-
end
|
170
|
-
|
171
|
-
# Removes all registered ignored packages
|
172
|
-
def clear_ignored
|
173
|
-
ignored_packages.clear
|
330
|
+
manifest_exclusions.clear
|
174
331
|
end
|
175
332
|
|
176
333
|
# The set of package names that are listed in the excluded_packages
|
177
334
|
# section of the manifest
|
178
|
-
|
179
|
-
@manifest_exclusions
|
180
|
-
end
|
335
|
+
attr_reader :manifest_exclusions
|
181
336
|
|
182
|
-
# A package_name => reason map of the exclusions added with #
|
337
|
+
# A package_name => reason map of the exclusions added with {#exclude_package}
|
183
338
|
# Exclusions listed in the manifest file are returned by #manifest_exclusions
|
184
339
|
attr_reader :automatic_exclusions
|
185
340
|
|
341
|
+
# @deprecated use {#exclude_package} instead
|
342
|
+
def add_exclusion(package_name, reason)
|
343
|
+
Autoproj.warn_deprecated __method__, "use #exclude_package instead"
|
344
|
+
exclude_package(package_name, reason)
|
345
|
+
end
|
346
|
+
|
186
347
|
# Exclude +package_name+ from the build. +reason+ is a string describing
|
187
348
|
# why the package is to be excluded.
|
188
|
-
def
|
189
|
-
|
349
|
+
def exclude_package(package_name, reason)
|
350
|
+
package = validate_package_name_argument(package_name, require_existing: false)
|
351
|
+
if meta = find_metapackage(package)
|
352
|
+
meta.each_package do |pkg|
|
353
|
+
automatic_exclusions[pkg.name] = "#{meta.name} is an excluded metapackage, and it includes #{pkg.name}: #{reason}"
|
354
|
+
end
|
355
|
+
else
|
356
|
+
automatic_exclusions[package] = reason
|
357
|
+
end
|
190
358
|
end
|
191
359
|
|
192
360
|
# Tests whether the given package is excluded in the manifest
|
193
361
|
def excluded_in_manifest?(package_name)
|
362
|
+
package_name = validate_package_name_argument(package_name)
|
194
363
|
manifest_exclusions.any? do |matcher|
|
195
364
|
if (pkg_set = metapackages[matcher]) && pkg_set.include?(package_name)
|
196
365
|
true
|
@@ -207,11 +376,15 @@ def excluded_in_manifest?(package_name)
|
|
207
376
|
# exclude_packages section of the manifest, or because they are
|
208
377
|
# disabled on this particular operating system.
|
209
378
|
def exclusion_reason(package_name)
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
379
|
+
package_name = validate_package_name_argument(package_name)
|
380
|
+
manifest_exclusions.any? do |matcher|
|
381
|
+
if (pkg_set = metapackages[matcher]) && pkg_set.include?(package_name)
|
382
|
+
return "#{pkg_set.name} is a metapackage listed in the exclude_packages section of the manifest, and it includes #{package_name}"
|
383
|
+
elsif Regexp.new(matcher) === package_name
|
384
|
+
return "#{package_name} is listed in the exclude_packages section of the manifest"
|
385
|
+
end
|
214
386
|
end
|
387
|
+
automatic_exclusions[package_name]
|
215
388
|
end
|
216
389
|
|
217
390
|
# Returns true if the given package name has been explicitely added to
|
@@ -224,65 +397,9 @@ def explicitely_selected_in_layout?(package_name)
|
|
224
397
|
normalized_layout.has_key?(package_name)
|
225
398
|
end
|
226
399
|
|
227
|
-
# True if the given package should not be built and its dependencies
|
228
|
-
# should be considered as met.
|
229
|
-
#
|
230
|
-
# This is useful to avoid building packages that are of no use for the
|
231
|
-
# user.
|
232
|
-
def excluded?(package_name)
|
233
|
-
package_name = package_name.to_str
|
234
|
-
|
235
|
-
if excluded_in_manifest?(package_name)
|
236
|
-
true
|
237
|
-
elsif automatic_exclusions.any? { |pkg_name, | pkg_name == package_name }
|
238
|
-
true
|
239
|
-
else
|
240
|
-
false
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
# Lists the autobuild files that are in the package sets we know of
|
245
|
-
def each_autobuild_file(source_name = nil, &block)
|
246
|
-
if !block_given?
|
247
|
-
return enum_for(__method__, source_name)
|
248
|
-
end
|
249
|
-
|
250
|
-
# This looks very inefficient, but it is because source names are
|
251
|
-
# contained in source.yml and we must therefore load that file to
|
252
|
-
# check the package set name ...
|
253
|
-
#
|
254
|
-
# And honestly I don't think someone will have 20 000 package sets
|
255
|
-
done_something = false
|
256
|
-
each_package_set do |source|
|
257
|
-
next if source_name && source.name != source_name
|
258
|
-
done_something = true
|
259
|
-
|
260
|
-
Dir.glob(File.join(source.local_dir, "*.autobuild")).sort.each do |file|
|
261
|
-
yield(source, file)
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
if source_name && !done_something
|
266
|
-
raise ConfigError.new(file), "in #{file}: package set '#{source_name}' does not exist"
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
# Yields each osdeps definition files that are present in our sources
|
271
|
-
def each_osdeps_file
|
272
|
-
if !block_given?
|
273
|
-
return enum_for(__method__)
|
274
|
-
end
|
275
|
-
|
276
|
-
each_package_set do |source|
|
277
|
-
Dir.glob(File.join(source.local_dir, "*.osdeps")).each do |file|
|
278
|
-
yield(source, file)
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
400
|
# True if some of the sources are remote sources
|
284
|
-
def
|
285
|
-
|
401
|
+
def has_remote_package_sets?
|
402
|
+
each_remote_package_set.any? { true }
|
286
403
|
end
|
287
404
|
|
288
405
|
# Like #each_package_set, but filters out local package sets
|
@@ -296,25 +413,6 @@ def each_remote_package_set
|
|
296
413
|
end
|
297
414
|
end
|
298
415
|
|
299
|
-
# Enumerates the version control information for all the package sets
|
300
|
-
# listed directly in the manifest file
|
301
|
-
#
|
302
|
-
# @yieldparam [VCSDefinition] vcs the package set VCS object
|
303
|
-
# @yieldparam [Hash] options additional import options
|
304
|
-
# @options options [Boolean] :auto_update (true) if true, the set of
|
305
|
-
# package sets declared as imports in package set's source.yml file
|
306
|
-
# will be auto-imported by autoproj, otherwise they won't
|
307
|
-
# @return [nil]
|
308
|
-
def each_raw_explicit_package_set
|
309
|
-
return enum_for(__method__) if !block_given?
|
310
|
-
(data['package_sets'] || []).map do |spec|
|
311
|
-
Autoproj.in_file(self.file) do
|
312
|
-
yield(*PackageSet.resolve_definition(self, spec))
|
313
|
-
end
|
314
|
-
end
|
315
|
-
nil
|
316
|
-
end
|
317
|
-
|
318
416
|
# Lists all package sets defined in this manifest, including the package
|
319
417
|
# sets that are auto-imported
|
320
418
|
#
|
@@ -326,20 +424,16 @@ def each_package_set(&block)
|
|
326
424
|
@package_sets.each(&block)
|
327
425
|
end
|
328
426
|
|
329
|
-
#
|
330
|
-
def
|
331
|
-
|
332
|
-
"use Ops::Configuration instead"
|
333
|
-
Ops::Configuration.new(Autoproj.workspace).load_and_update_package_sets
|
334
|
-
end
|
335
|
-
|
336
|
-
# Returns a package set that is used by autoproj for its own purposes
|
337
|
-
def local_package_set
|
338
|
-
each_package_set.find { |s| s.kind_of?(LocalPackageSet) }
|
427
|
+
# Reset the list of package sets
|
428
|
+
def reset_package_sets
|
429
|
+
@package_sets.clear
|
339
430
|
end
|
340
431
|
|
341
432
|
# Registers a new package set
|
433
|
+
#
|
434
|
+
# @param [PackageSet] pkg_set the package set object
|
342
435
|
def register_package_set(pkg_set)
|
436
|
+
invalidate_ignored_package_names
|
343
437
|
metapackage(pkg_set.name)
|
344
438
|
metapackage("#{pkg_set.name}.all")
|
345
439
|
@package_sets << pkg_set
|
@@ -353,6 +447,7 @@ def register_package_set(pkg_set)
|
|
353
447
|
# @param [String] file the file in which the package is defined
|
354
448
|
# @return [PackageDefinition]
|
355
449
|
def register_package(package, block = nil, package_set = main_package_set, file = nil)
|
450
|
+
invalidate_ignored_package_names
|
356
451
|
pkg = PackageDefinition.new(package, package_set, file)
|
357
452
|
if block
|
358
453
|
pkg.add_setup_block(block)
|
@@ -363,52 +458,43 @@ def register_package(package, block = nil, package_set = main_package_set, file
|
|
363
458
|
pkg
|
364
459
|
end
|
365
460
|
|
366
|
-
#
|
461
|
+
# The autoproj description of a package by its name
|
367
462
|
#
|
368
|
-
# @param [String]
|
369
|
-
# @return [
|
370
|
-
|
371
|
-
|
372
|
-
def definition_package_set(package_name)
|
373
|
-
if pkg_def = @packages[package_name]
|
374
|
-
pkg_def.package_set
|
375
|
-
else raise ArgumentError, "no package called #{package_name}"
|
376
|
-
end
|
463
|
+
# @param [String,#name] name the package name
|
464
|
+
# @return [PackageDefinition,nil]
|
465
|
+
def find_package_definition(name)
|
466
|
+
packages[validate_package_name_argument(name, require_existing: false)]
|
377
467
|
end
|
378
468
|
|
379
|
-
# @deprecated use {
|
380
|
-
|
381
|
-
|
469
|
+
# @deprecated use {#find_package_definition}(pkg_name).package_set
|
470
|
+
# instead
|
471
|
+
def definition_source(name)
|
472
|
+
Autoproj.warn_deprecated __method__, "use #package_definition_by_name(name).package_set instead"
|
473
|
+
package_definition_by_name(name).package_set
|
382
474
|
end
|
383
475
|
|
384
|
-
#
|
385
|
-
#
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
# package
|
390
|
-
def definition_file(package_name)
|
391
|
-
if pkg_def = @packages[package_name]
|
392
|
-
pkg_def.file
|
393
|
-
else raise ArgumentError, "no package called #{package_name}"
|
394
|
-
end
|
476
|
+
# @deprecated use {#find_package_definition}(pkg_name).package_set
|
477
|
+
# instead
|
478
|
+
def definition_package_set(name)
|
479
|
+
Autoproj.warn_deprecated __method__, "use #package_definition_by_name(name).package_set instead"
|
480
|
+
package_definition_by_name(name).package_set
|
395
481
|
end
|
396
482
|
|
397
483
|
# @deprecated use {#find_package_definition} instead
|
398
|
-
def
|
484
|
+
def package(name)
|
485
|
+
Autoproj.warn_deprecated "Manifest#package is deprecated, use #package_definition_by_name instead"
|
399
486
|
find_package_definition(name)
|
400
487
|
end
|
401
488
|
|
402
|
-
#
|
489
|
+
# Resolve a package definition by name
|
403
490
|
#
|
404
|
-
#
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
491
|
+
# Unlike {#find_package_definition}, raise if the package does not exist
|
492
|
+
def package_definition_by_name(name)
|
493
|
+
if pkg = find_package_definition(name)
|
494
|
+
pkg
|
495
|
+
else
|
496
|
+
raise ArgumentError, "no package defined named '#{name}'"
|
409
497
|
end
|
410
|
-
|
411
|
-
packages[name.to_str]
|
412
498
|
end
|
413
499
|
|
414
500
|
# The autobuild description of a package by its name
|
@@ -416,23 +502,11 @@ def find_package_definition(name)
|
|
416
502
|
# @param [String,#name] name the package name
|
417
503
|
# @return [Autobuild::Package,nil]
|
418
504
|
def find_autobuild_package(name)
|
419
|
-
if pkg =
|
505
|
+
if pkg = find_package_definition(name)
|
420
506
|
pkg.autobuild
|
421
507
|
end
|
422
508
|
end
|
423
509
|
|
424
|
-
# @deprecated use {#find_package} instead
|
425
|
-
def package(name)
|
426
|
-
find_package(name)
|
427
|
-
end
|
428
|
-
|
429
|
-
# @deprecated use {each_autobuild_package} instead
|
430
|
-
def each_package(&block)
|
431
|
-
Autoproj.warn "Manifest#each_package is deprecated, use each_autobuild_package instead"
|
432
|
-
Autoproj.warn " " + caller.join("\n ")
|
433
|
-
each_autobuild_package(&block)
|
434
|
-
end
|
435
|
-
|
436
510
|
# Lists all defined packages
|
437
511
|
#
|
438
512
|
# @yieldparam [PackageDefinition] pkg
|
@@ -449,58 +523,41 @@ def each_autobuild_package
|
|
449
523
|
each_package_definition { |pkg| yield(pkg.autobuild) }
|
450
524
|
end
|
451
525
|
|
452
|
-
# @
|
453
|
-
# Ops::Tools into your class to get it as instance method
|
454
|
-
def self.create_autobuild_package(vcs, text_name, into)
|
455
|
-
Autoproj.warn_deprecated __method__, "use Ops::Tools.create_autobuild_package instead"
|
456
|
-
Ops::Tools.create_autobuild_package(vcs, text_name, into)
|
457
|
-
end
|
458
|
-
|
459
|
-
# @deprecated use Ops::Configuration#update_main_configuration
|
460
|
-
def update_yourself(only_local = false)
|
461
|
-
Autoproj.warn_deprecated __method__, "use Ops::Configuration instead"
|
462
|
-
Ops::Configuration.new(Autoproj.workspace).update_main_configuration(only_local)
|
463
|
-
end
|
464
|
-
|
465
|
-
# @deprecated use Ops::Configuration.update_remote_package_set
|
466
|
-
def update_remote_set(vcs, only_local = false)
|
467
|
-
Autoproj.warn_deprecated __method__, "use Ops::Configuration instead"
|
468
|
-
Ops::Configuration.update_remote_package_set(vcs, only_local)
|
469
|
-
end
|
470
|
-
|
471
|
-
# Compute the VCS definition for a given package
|
526
|
+
# @overload importer_definition_for(package, mainline: nil, require_existing: true, package_set: nil)
|
472
527
|
#
|
473
|
-
# @param [
|
474
|
-
# @param [PackageSet,nil]
|
475
|
-
#
|
476
|
-
#
|
528
|
+
# @param [PackageDefinition] package the name of the package to be resolved
|
529
|
+
# @param [PackageSet,nil] mainline the reference package set for which
|
530
|
+
# we want to compute the importer definition. Pass package.package_set
|
531
|
+
# if you want to avoid applying any override
|
477
532
|
# @return [VCSDefinition] the VCS definition object
|
478
|
-
def importer_definition_for(
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
533
|
+
def importer_definition_for(package, _package_set = nil, mainline: nil, require_existing: true, package_set: nil)
|
534
|
+
if _package_set
|
535
|
+
Autoproj.warn_deprecated "calling #importer_definition_for with the package set as second argument is deprecated, use the package_set: keyword argument instead"
|
536
|
+
require_existing = false
|
537
|
+
end
|
538
|
+
package_name = validate_package_name_argument(package, require_existing: require_existing)
|
539
|
+
package_set = _package_set || package_set || package.package_set
|
540
|
+
mainline = if mainline == true
|
541
|
+
package_set
|
542
|
+
else mainline
|
543
|
+
end
|
487
544
|
|
488
|
-
|
489
|
-
|
545
|
+
# package_name is already validated, do not re-validate
|
546
|
+
vcs = package_set.importer_definition_for(package_name, require_existing: false)
|
490
547
|
|
491
|
-
# Get the sets that come *after* the one that defines the package to
|
492
|
-
# apply the overrides
|
493
548
|
package_sets = each_package_set.to_a.dup
|
494
|
-
|
495
|
-
|
496
|
-
|
549
|
+
index = package_sets.find_index(package_set)
|
550
|
+
if !index
|
551
|
+
raise RuntimeError, "found inconsistency: package #{package_name} is not in a package set of #{self}"
|
552
|
+
end
|
553
|
+
|
554
|
+
if package_sets[0, index + 1].include?(mainline)
|
555
|
+
return vcs
|
497
556
|
end
|
498
|
-
set = package_sets.shift
|
499
|
-
return vcs if set == mainline
|
500
557
|
|
501
558
|
# Then apply the overrides
|
502
|
-
package_sets.inject(vcs) do |updated_vcs, pkg_set|
|
503
|
-
updated_vcs = pkg_set.overrides_for(package_name, updated_vcs)
|
559
|
+
package_sets[(index + 1)..-1].inject(vcs) do |updated_vcs, pkg_set|
|
560
|
+
updated_vcs = pkg_set.overrides_for(package_name, updated_vcs, require_existing: false)
|
504
561
|
return updated_vcs if pkg_set == mainline
|
505
562
|
updated_vcs
|
506
563
|
end
|
@@ -522,45 +579,59 @@ def importer_definition_for(package_name, package_set = definition_package_set(p
|
|
522
579
|
# * S1 must have a VCS line for P
|
523
580
|
# * S0 can have a VCS line for P, which would override the one defined
|
524
581
|
# by S1
|
525
|
-
def load_importers(
|
582
|
+
def load_importers(mainline: nil)
|
526
583
|
packages.each_value do |pkg|
|
527
|
-
|
528
|
-
|
529
|
-
|
584
|
+
package_mainline =
|
585
|
+
if mainline == true
|
586
|
+
pkg.package_set
|
587
|
+
else mainline
|
588
|
+
end
|
589
|
+
vcs = importer_definition_for(pkg, mainline: package_mainline)
|
530
590
|
|
531
|
-
if vcs
|
532
|
-
pkg.
|
533
|
-
|
534
|
-
|
535
|
-
|
591
|
+
if vcs.none?
|
592
|
+
if pkg.package_set.importer_definition_for(pkg).none?
|
593
|
+
if (pkg.package_set != main_package_set) || !File.exist?(pkg.autobuild.srcdir)
|
594
|
+
raise ConfigError.new, "package set #{pkg.package_set.name} defines the package '#{pkg.name}', but does not provide a version control definition for it"
|
595
|
+
end
|
596
|
+
end
|
536
597
|
end
|
598
|
+
|
599
|
+
pkg.vcs = vcs
|
600
|
+
pkg.autobuild.importer = vcs.create_autobuild_importer
|
537
601
|
end
|
538
602
|
end
|
539
603
|
|
540
604
|
# Checks if there is a package with a given name
|
541
605
|
#
|
542
|
-
# @param [String] name
|
606
|
+
# @param [String] name the name of a source or osdep package
|
543
607
|
# @return [Boolean]
|
544
608
|
def has_package?(name)
|
545
|
-
packages.has_key?(name)
|
609
|
+
packages.has_key?(name) || os_package_resolver.include?(name)
|
546
610
|
end
|
547
611
|
|
548
|
-
#
|
549
|
-
# autoproj installation
|
612
|
+
# Checks if there is a package set with a given name
|
550
613
|
def has_package_set?(name)
|
614
|
+
!!find_package_set(name)
|
615
|
+
end
|
616
|
+
|
617
|
+
# Returns a package set from its name
|
618
|
+
def find_package_set(name)
|
551
619
|
each_package_set.find { |set| set.name == name }
|
552
620
|
end
|
553
621
|
|
554
|
-
#
|
555
|
-
#
|
622
|
+
# The PackageSet object for the given package set
|
623
|
+
#
|
624
|
+
# @return [PackageSet] the package set
|
625
|
+
# @raise [ArgumentError] if none exists with that name
|
556
626
|
def package_set(name)
|
557
|
-
set =
|
558
|
-
|
627
|
+
if set = find_package_set(name)
|
628
|
+
set
|
629
|
+
else
|
559
630
|
raise ArgumentError, "no package set called #{name} exists"
|
560
631
|
end
|
561
|
-
set
|
562
632
|
end
|
563
633
|
|
634
|
+
# The root package set, which represents the workspace itself
|
564
635
|
def main_package_set
|
565
636
|
each_package_set.find(&:main?)
|
566
637
|
end
|
@@ -572,7 +643,7 @@ def main_package_set
|
|
572
643
|
# package set).
|
573
644
|
#
|
574
645
|
# @return [nil,Array] either nil if there is no such osdep, or a list of
|
575
|
-
# (type, package_name) pairs where type is either :package or :
|
646
|
+
# (type, package_name) pairs where type is either :package or :osdeps and
|
576
647
|
# package_name the corresponding package name
|
577
648
|
# @raise [PackageNotFound] if the given package name cannot be resolved
|
578
649
|
# into a package. If {#accept_unavailable_osdeps?} is false (the
|
@@ -599,27 +670,6 @@ def resolve_package_name(name)
|
|
599
670
|
result
|
600
671
|
end
|
601
672
|
|
602
|
-
# Resolves all the source package dependencies for given packages
|
603
|
-
#
|
604
|
-
# @param [Set<String>] the set of package names of which we want to
|
605
|
-
# discover the dependencies
|
606
|
-
# @return [Set<String>] the set of all package names that the packages designed
|
607
|
-
# by root_names depend on
|
608
|
-
def resolve_packages_dependencies(*root_names)
|
609
|
-
result = Set.new
|
610
|
-
queue = root_names.dup
|
611
|
-
while pkg_name = queue.shift
|
612
|
-
next if result.include?(pkg_name)
|
613
|
-
result << pkg_name
|
614
|
-
|
615
|
-
pkg = find_autobuild_package(pkg_name)
|
616
|
-
pkg.dependencies.each do |dep_name|
|
617
|
-
queue << dep_name
|
618
|
-
end
|
619
|
-
end
|
620
|
-
result
|
621
|
-
end
|
622
|
-
|
623
673
|
# @api private
|
624
674
|
#
|
625
675
|
# Resolves a package name, where +name+ cannot be resolved as a
|
@@ -629,7 +679,7 @@ def resolve_packages_dependencies(*root_names)
|
|
629
679
|
# directly
|
630
680
|
#
|
631
681
|
# @return [nil,Array] either nil if there is no such osdep, or a list of
|
632
|
-
# (type, package_name) pairs where type is either :package or :
|
682
|
+
# (type, package_name) pairs where type is either :package or :osdeps and
|
633
683
|
# package_name the corresponding package name
|
634
684
|
def resolve_single_package_name(name)
|
635
685
|
resolve_package_name_as_osdep(name)
|
@@ -695,28 +745,11 @@ def resolve_package_name_as_osdep(name)
|
|
695
745
|
elsif osdeps_available || accept_unavailable_osdeps?
|
696
746
|
return [[:osdeps, name]]
|
697
747
|
elsif osdeps_availability == OSPackageResolver::WRONG_OS
|
698
|
-
raise PackageNotFound, "#{name} is an osdep, but it is not available for this operating system"
|
748
|
+
raise PackageNotFound, "#{name} is an osdep, but it is not available for this operating system (#{os_package_resolver.operating_system})"
|
699
749
|
elsif osdeps_availability == OSPackageResolver::UNKNOWN_OS
|
700
750
|
raise PackageNotFound, "#{name} is an osdep, but the local operating system is unavailable"
|
701
751
|
elsif osdeps_availability == OSPackageResolver::NONEXISTENT
|
702
|
-
raise PackageNotFound, "#{name} is an osdep, but it is explicitely marked as 'nonexistent' for this operating system"
|
703
|
-
end
|
704
|
-
end
|
705
|
-
|
706
|
-
# +name+ can either be the name of a source or the name of a package. In
|
707
|
-
# the first case, we return all packages defined by that source. In the
|
708
|
-
# latter case, we return the singleton array [name]
|
709
|
-
def resolve_package_set(name)
|
710
|
-
if find_autobuild_package(name)
|
711
|
-
[name]
|
712
|
-
else
|
713
|
-
pkg_set = find_metapackage(name)
|
714
|
-
if !pkg_set
|
715
|
-
raise UnknownPackage.new(name), "#{name} is neither a package nor a package set name. Packages in autoproj must be declared in an autobuild file."
|
716
|
-
end
|
717
|
-
pkg_set.each_package.
|
718
|
-
map(&:name).
|
719
|
-
find_all { |pkg_name| !os_package_resolver.has?(pkg_name) }
|
752
|
+
raise PackageNotFound, "#{name} is an osdep, but it is explicitely marked as 'nonexistent' for this operating system (#{os_package_resolver.operating_system})"
|
720
753
|
end
|
721
754
|
end
|
722
755
|
|
@@ -743,14 +776,19 @@ def find_metapackage(name)
|
|
743
776
|
#
|
744
777
|
def metapackage(name, *packages, &block)
|
745
778
|
meta = (@metapackages[name.to_s] ||= Metapackage.new(name))
|
746
|
-
packages.each do |
|
747
|
-
if
|
748
|
-
|
749
|
-
|
750
|
-
|
779
|
+
packages.each do |arg|
|
780
|
+
if !arg.respond_to?(:to_str)
|
781
|
+
meta.add(arg)
|
782
|
+
elsif pkg = find_autobuild_package(arg)
|
783
|
+
meta.add(pkg)
|
784
|
+
elsif pkg_set = find_metapackage(arg)
|
785
|
+
pkg_set.each_package do |pkg_in_set|
|
786
|
+
meta.add(pkg_in_set)
|
751
787
|
end
|
788
|
+
elsif os_package_resolver.has?(arg)
|
789
|
+
raise ArgumentError, "cannot specify the osdep #{arg} as an element of a metapackage"
|
752
790
|
else
|
753
|
-
|
791
|
+
raise PackageNotFound, "cannot find a package called #{arg}"
|
754
792
|
end
|
755
793
|
end
|
756
794
|
|
@@ -771,7 +809,7 @@ def each_metapackage(&block)
|
|
771
809
|
# Returns the packages selected in this manifest's layout
|
772
810
|
#
|
773
811
|
# @return [PackageSelection]
|
774
|
-
def layout_packages(validate)
|
812
|
+
def layout_packages(validate = true)
|
775
813
|
result = PackageSelection.new
|
776
814
|
Autoproj.in_file(self.file) do
|
777
815
|
normalized_layout.each_key do |pkg_or_set|
|
@@ -780,10 +818,11 @@ def layout_packages(validate)
|
|
780
818
|
meta.weak_dependencies?
|
781
819
|
end
|
782
820
|
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
821
|
+
resolve_package_name(pkg_or_set).each do |pkg_type, pkg_name|
|
822
|
+
result.select(pkg_or_set, pkg_name, osdep: (pkg_type == :osdeps), weak: weak)
|
823
|
+
end
|
824
|
+
rescue PackageNotFound => e
|
825
|
+
raise e, "#{pkg_or_set}, which is selected in the layout, is unknown: #{e.message}", e.backtrace
|
787
826
|
end
|
788
827
|
end
|
789
828
|
end
|
@@ -798,37 +837,17 @@ def layout_packages(validate)
|
|
798
837
|
result
|
799
838
|
end
|
800
839
|
|
801
|
-
# Enumerates the sublayouts defined in +layout_def+.
|
802
|
-
def each_sublayout(layout_def)
|
803
|
-
layout_def.each do |value|
|
804
|
-
if value.kind_of?(Hash)
|
805
|
-
name, layout = value.find { true }
|
806
|
-
yield(name, layout)
|
807
|
-
end
|
808
|
-
end
|
809
|
-
end
|
810
|
-
|
811
840
|
# Returns the set of package names that are explicitely listed in the
|
812
841
|
# layout, minus the excluded and ignored ones
|
813
842
|
def all_layout_packages(validate = true)
|
814
843
|
default_packages(validate)
|
815
844
|
end
|
816
845
|
|
817
|
-
# Returns all defined package names
|
846
|
+
# Returns all defined package names
|
818
847
|
def all_package_names
|
819
848
|
each_autobuild_package.map(&:name)
|
820
849
|
end
|
821
850
|
|
822
|
-
# Returns all the packages that can be built in this installation
|
823
|
-
def all_packages
|
824
|
-
result = Set.new
|
825
|
-
each_package_set do |pkg_set|
|
826
|
-
result |= metapackage(pkg_set.name).packages.map(&:name).to_set
|
827
|
-
end
|
828
|
-
result.to_a.
|
829
|
-
find_all { |pkg_name| !os_package_resolver.has?(pkg_name) }
|
830
|
-
end
|
831
|
-
|
832
851
|
# Returns true if +name+ is a valid package and is included in the build
|
833
852
|
#
|
834
853
|
# If +validate+ is true, the method will raise ArgumentError if the
|
@@ -837,14 +856,8 @@ def all_packages
|
|
837
856
|
# If it is false, the method will simply return false on non-defined
|
838
857
|
# packages
|
839
858
|
def package_enabled?(name, validate = true)
|
840
|
-
|
841
|
-
|
842
|
-
raise ArgumentError, "package #{name} does not exist"
|
843
|
-
end
|
844
|
-
return false
|
845
|
-
end
|
846
|
-
|
847
|
-
!excluded?(name)
|
859
|
+
Autoproj.warn_deprecated "#package_enabled? and #package_selected? were broken in autoproj v1, and there are usually other ways to get the same effect (as e.g. splitting package sets). Feel free to contact the autoproj developers if you have a use case that demands this functionality. For now, this method returns true for backward compatibility reasons."
|
860
|
+
true
|
848
861
|
end
|
849
862
|
|
850
863
|
# Returns true if +name+ is a valid package and is neither excluded from
|
@@ -856,48 +869,68 @@ def package_enabled?(name, validate = true)
|
|
856
869
|
# If it is false, the method will simply return false on non-defined
|
857
870
|
# packages
|
858
871
|
def package_selected?(name, validate = true)
|
859
|
-
|
860
|
-
|
872
|
+
Autoproj.warn_deprecated "#package_enabled? and #package_selected? were broken in autoproj v1, and there are usually other ways to get the same effect (as e.g. splitting package sets). Feel free to contact the autoproj developers if you have a use case that demands this functionality. For now, this method returns true for backward compatibility reasons."
|
873
|
+
true
|
874
|
+
end
|
875
|
+
|
876
|
+
# Returns the set of source packages that are selected by the layout
|
877
|
+
#
|
878
|
+
# @return [Array<PackageDefinition>]
|
879
|
+
def all_selected_source_packages(validate = true)
|
880
|
+
result = Set.new
|
881
|
+
selection = default_packages(validate)
|
882
|
+
|
883
|
+
root_sources = selection.each_source_package_name.to_set
|
884
|
+
root_sources.each do |pkg_name|
|
885
|
+
find_autobuild_package(pkg_name).all_dependencies(result)
|
886
|
+
end
|
887
|
+
result.merge(root_sources).map do |pkg_name|
|
888
|
+
find_package_definition(pkg_name)
|
861
889
|
end
|
862
890
|
end
|
863
891
|
|
864
892
|
# Returns the set of packages that are selected by the layout
|
893
|
+
#
|
894
|
+
# Unless {#default_packages}, it returns both the selected packages and
|
895
|
+
# the dependencies (resolved recursively)
|
896
|
+
#
|
897
|
+
# @return [Array<String>] a list of source and osdep package names
|
865
898
|
def all_selected_packages(validate = true)
|
866
899
|
result = Set.new
|
867
|
-
|
868
|
-
|
869
|
-
|
900
|
+
selection = default_packages(validate)
|
901
|
+
|
902
|
+
root_sources = selection.each_source_package_name.to_set
|
903
|
+
root_sources.each do |pkg_name|
|
904
|
+
find_autobuild_package(pkg_name).all_dependencies_with_osdeps(result)
|
870
905
|
end
|
871
|
-
result |
|
906
|
+
result | root_sources | selection.each_osdep_package_name.to_set
|
872
907
|
end
|
873
908
|
|
874
909
|
# Returns the set of packages that should be built if the user does not
|
875
910
|
# specify any on the command line
|
876
911
|
def default_packages(validate = true)
|
877
|
-
if
|
878
|
-
|
912
|
+
if has_layout?
|
913
|
+
layout_packages(validate)
|
879
914
|
else
|
880
915
|
result = PackageSelection.new
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
result.select(pkg_name, pkg_name)
|
916
|
+
all_package_names.each do |pkg_name|
|
917
|
+
package_type, package_name = resolve_single_package_name(pkg_name).first
|
918
|
+
next if excluded?(package_name) || ignored?(package_name)
|
919
|
+
result.select(package_name, package_name, osdep: (package_type == :osdeps))
|
886
920
|
end
|
887
921
|
result
|
888
922
|
end
|
889
923
|
end
|
890
924
|
|
891
|
-
#
|
892
|
-
#
|
893
|
-
|
894
|
-
|
925
|
+
# @api private
|
926
|
+
#
|
927
|
+
# Compute a layout structure that is normalized
|
895
928
|
def compute_normalized_layout(result, layout_level, layout_data)
|
896
929
|
layout_data.each do |value|
|
897
930
|
if value.kind_of?(Hash)
|
898
931
|
subname, subdef = value.find { true }
|
899
932
|
if subdef
|
900
|
-
|
933
|
+
compute_normalized_layout(result, "#{layout_level}#{subname}/", subdef)
|
901
934
|
end
|
902
935
|
else
|
903
936
|
result[value] = layout_level
|
@@ -906,19 +939,28 @@ def compute_normalized_layout(result, layout_level, layout_data)
|
|
906
939
|
result
|
907
940
|
end
|
908
941
|
|
909
|
-
# Returns the
|
942
|
+
# Returns the level of the layout into which of a certain package
|
943
|
+
# would be selected
|
944
|
+
#
|
945
|
+
# @return [String]
|
910
946
|
def whereis(package_name)
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
947
|
+
package_name = validate_package_name_argument(package_name)
|
948
|
+
|
949
|
+
matches = [package_name]
|
950
|
+
if source_package = find_package_definition(package_name)
|
951
|
+
each_metapackage do |meta|
|
952
|
+
if meta.include?(source_package)
|
953
|
+
matches << meta.name
|
954
|
+
end
|
955
|
+
end
|
915
956
|
end
|
916
|
-
end
|
917
957
|
|
918
|
-
|
919
|
-
|
920
|
-
|
958
|
+
matches.each do |name|
|
959
|
+
if place = normalized_layout[name]
|
960
|
+
return place
|
961
|
+
end
|
921
962
|
end
|
963
|
+
'/'
|
922
964
|
end
|
923
965
|
|
924
966
|
# Loads the package's manifest.xml file for the current package
|
@@ -927,37 +969,31 @@ def resolve_optional_dependencies
|
|
927
969
|
# warning. This will later be changed into an error.
|
928
970
|
def load_package_manifest(pkg)
|
929
971
|
if pkg.respond_to?(:to_str)
|
930
|
-
|
931
|
-
|
972
|
+
pkg_definition = find_package_definition(pkg)
|
973
|
+
if !pkg_definition
|
974
|
+
raise ArgumentError, "#{pkg} is not a known package in #{self}"
|
975
|
+
end
|
976
|
+
pkg = pkg_definition
|
932
977
|
end
|
933
|
-
package, package_set
|
978
|
+
package, package_set = pkg.autobuild, pkg.package_set
|
934
979
|
|
935
|
-
|
936
|
-
|
980
|
+
# Look for the package's manifest.xml, but fallback to a manifest in
|
981
|
+
# the package set if present
|
982
|
+
manifest_paths = [File.join(package.srcdir, "manifest.xml")]
|
983
|
+
if package_set.local_dir
|
984
|
+
manifest_paths << File.join(package_set.local_dir, "manifests", package.name + ".xml")
|
937
985
|
end
|
938
|
-
|
939
|
-
manifest_paths =
|
940
|
-
[File.join(package_set.local_dir, "manifests", package.name + ".xml"), File.join(package.srcdir, "manifest.xml")]
|
941
986
|
manifest_path = manifest_paths.find do |path|
|
942
|
-
File.
|
943
|
-
File.file?(path)
|
987
|
+
File.file?(path)
|
944
988
|
end
|
945
989
|
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
else
|
952
|
-
pkg.autobuild.description
|
953
|
-
end
|
954
|
-
else
|
955
|
-
PackageManifest.load(package, manifest_path)
|
956
|
-
end
|
957
|
-
|
958
|
-
pkg.autobuild.description = manifest
|
959
|
-
package_manifests[package.name] = manifest
|
990
|
+
if manifest_path
|
991
|
+
pkg.autobuild.description = PackageManifest.load(package, manifest_path)
|
992
|
+
elsif pkg.autobuild.description.null?
|
993
|
+
Autoproj.warn "#{package.name} from #{package_set.name} does not have a manifest"
|
994
|
+
end
|
960
995
|
|
996
|
+
manifest = pkg.autobuild.description
|
961
997
|
manifest.each_dependency(pkg.modes) do |name, is_optional|
|
962
998
|
begin
|
963
999
|
if is_optional
|
@@ -965,9 +1001,6 @@ def load_package_manifest(pkg)
|
|
965
1001
|
else
|
966
1002
|
package.depends_on name
|
967
1003
|
end
|
968
|
-
rescue Autobuild::ConfigException => e
|
969
|
-
raise ConfigError.new(manifest_path),
|
970
|
-
"manifest #{manifest_path} of #{package.name} from #{package_set.name} lists '#{name}' as dependency, which is listed in the layout of #{file} but has no autobuild definition", e.backtrace
|
971
1004
|
rescue ConfigError => e
|
972
1005
|
raise ConfigError.new(manifest_path),
|
973
1006
|
"manifest #{manifest_path} of #{package.name} from #{package_set.name} lists '#{name}' as dependency, but it is neither a normal package nor an osdeps package. osdeps reports: #{e.message}", e.backtrace
|
@@ -976,59 +1009,6 @@ def load_package_manifest(pkg)
|
|
976
1009
|
manifest
|
977
1010
|
end
|
978
1011
|
|
979
|
-
# Loads the manifests for all packages known to this project.
|
980
|
-
#
|
981
|
-
# See #load_package_manifest
|
982
|
-
def load_package_manifests(selected_packages)
|
983
|
-
selected_packages.each(&:load_package_manifest)
|
984
|
-
end
|
985
|
-
|
986
|
-
# Disable all automatic imports from the given package set name
|
987
|
-
def disable_imports_from(pkg_set_name)
|
988
|
-
@disabled_imports << pkg_set_name
|
989
|
-
end
|
990
|
-
|
991
|
-
# call-seq:
|
992
|
-
# list_os_packages(packages) => required_packages, ospkg_to_pkg
|
993
|
-
#
|
994
|
-
# Returns the set of dependencies required by the listed packages.
|
995
|
-
#
|
996
|
-
# +required_packages+ is the set of osdeps names that are required for
|
997
|
-
# +packages+ and +ospkg_to_pkg+ a mapping from the osdeps name to the
|
998
|
-
# set of packages that require this OS package.
|
999
|
-
def list_os_packages(packages)
|
1000
|
-
required_os_packages = Set.new
|
1001
|
-
package_os_deps = Hash.new { |h, k| h[k] = Array.new }
|
1002
|
-
packages.each do |pkg_name|
|
1003
|
-
pkg = find_autobuild_package(pkg_name)
|
1004
|
-
if !pkg
|
1005
|
-
raise InternalError, "internal error: #{pkg_name} is not a package"
|
1006
|
-
end
|
1007
|
-
|
1008
|
-
pkg.os_packages.each do |osdep_name|
|
1009
|
-
package_os_deps[osdep_name] << pkg_name
|
1010
|
-
required_os_packages << osdep_name
|
1011
|
-
end
|
1012
|
-
end
|
1013
|
-
|
1014
|
-
return required_os_packages, package_os_deps
|
1015
|
-
end
|
1016
|
-
|
1017
|
-
def filter_os_packages(required_os_packages, package_os_deps)
|
1018
|
-
required_os_packages.find_all do |pkg|
|
1019
|
-
if excluded?(pkg)
|
1020
|
-
raise ConfigError.new, "the osdeps package #{pkg} is excluded from the build in #{file}. It is required by #{package_os_deps[pkg].join(", ")}"
|
1021
|
-
end
|
1022
|
-
if ignored?(pkg)
|
1023
|
-
if Autoproj.verbose
|
1024
|
-
Autoproj.message "ignoring osdeps package #{pkg}"
|
1025
|
-
end
|
1026
|
-
false
|
1027
|
-
else true
|
1028
|
-
end
|
1029
|
-
end
|
1030
|
-
end
|
1031
|
-
|
1032
1012
|
# The set of overrides added with #add_osdeps_overrides
|
1033
1013
|
attr_reader :osdeps_overrides
|
1034
1014
|
|
@@ -1089,38 +1069,30 @@ def update_selection(selection, user_selection_string, name, weak)
|
|
1089
1069
|
# name, or a prefix of the package's source directory. For osdeps, it
|
1090
1070
|
# has to be the plain package name
|
1091
1071
|
# @return [PackageSelection, Array<String>]
|
1092
|
-
def expand_package_selection(selection,
|
1093
|
-
options = Kernel.validate_options options, filter: true
|
1072
|
+
def expand_package_selection(selection, filter: true)
|
1094
1073
|
result = PackageSelection.new
|
1095
1074
|
|
1096
|
-
|
1097
|
-
# package set names. When it comes to packages (NOT package sets),
|
1098
|
-
# we prefer the ones selected in the layout
|
1099
|
-
all_selected_packages = self.all_selected_packages
|
1100
|
-
candidates = all_selected_packages.to_a +
|
1101
|
-
each_metapackage.map { |metapkg| [metapkg.name, metapkg.weak_dependencies?] }
|
1102
|
-
selection.each do |sel|
|
1103
|
-
match_pkg_name = Regexp.new(Regexp.quote(sel))
|
1104
|
-
candidates.each do |name, weak|
|
1105
|
-
next if name !~ match_pkg_name
|
1106
|
-
update_selection(result, sel, name, true)
|
1107
|
-
end
|
1108
|
-
end
|
1109
|
-
|
1110
|
-
pending_selections = Hash.new { |h, k| h[k] = Array.new }
|
1111
|
-
|
1112
|
-
# Finally, check for partial matches
|
1075
|
+
all_selected_packages = self.all_selected_packages.to_set
|
1113
1076
|
all_source_package_names = self.all_package_names
|
1114
1077
|
all_osdeps_package_names = os_package_resolver.all_package_names
|
1115
1078
|
selection.each do |sel|
|
1116
1079
|
match_pkg_name = Regexp.new(Regexp.quote(sel))
|
1117
1080
|
all_matches = Array.new
|
1081
|
+
each_metapackage do |meta_pkg|
|
1082
|
+
if meta_pkg.name =~ match_pkg_name
|
1083
|
+
all_matches << [meta_pkg.name, meta_pkg.name == sel]
|
1084
|
+
end
|
1085
|
+
end
|
1118
1086
|
all_source_package_names.each do |pkg_name|
|
1119
1087
|
pkg = find_autobuild_package(pkg_name)
|
1120
|
-
if
|
1121
|
-
|
1122
|
-
|
1123
|
-
all_matches << [
|
1088
|
+
if pkg.name =~ match_pkg_name
|
1089
|
+
all_matches << [pkg.name, pkg.name == sel]
|
1090
|
+
elsif "#{sel}/".start_with?("#{pkg.srcdir}/")
|
1091
|
+
all_matches << [pkg.name, true]
|
1092
|
+
elsif pkg.respond_to?(:builddir) && "#{sel}/".start_with?("#{pkg.builddir}/")
|
1093
|
+
all_matches << [pkg.name, true]
|
1094
|
+
elsif pkg.srcdir.start_with?(sel) && all_selected_packages.include?(pkg.name)
|
1095
|
+
all_matches << [pkg.name, false]
|
1124
1096
|
end
|
1125
1097
|
end
|
1126
1098
|
all_osdeps_package_names.each do |pkg_name|
|
@@ -1129,34 +1101,28 @@ def expand_package_selection(selection, options = Hash.new)
|
|
1129
1101
|
end
|
1130
1102
|
end
|
1131
1103
|
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1104
|
+
exact_matches, partial_matches =
|
1105
|
+
all_matches.partition { |_, exact_match| exact_match }
|
1106
|
+
selected_partial_matches, not_selected_partial_matches =
|
1107
|
+
partial_matches.partition { |pkg_name, _| all_selected_packages.include?(pkg_name) }
|
1108
|
+
if result.has_match_for?(sel)
|
1109
|
+
not_selected_partial_matches.clear
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
matches = [exact_matches, selected_partial_matches, not_selected_partial_matches].
|
1113
|
+
find { |m| !m.empty? }
|
1114
|
+
if matches
|
1115
|
+
matches.each do |pkg_name, _|
|
1141
1116
|
update_selection(result, sel, pkg_name, true)
|
1142
1117
|
end
|
1143
1118
|
end
|
1144
1119
|
end
|
1145
1120
|
|
1146
|
-
if
|
1121
|
+
if filter
|
1147
1122
|
result.filter_excluded_and_ignored_packages(self)
|
1148
1123
|
end
|
1149
1124
|
|
1150
1125
|
nonresolved = selection - result.matches.keys
|
1151
|
-
nonresolved.delete_if do |sel|
|
1152
|
-
if pending = pending_selections.fetch(sel, nil)
|
1153
|
-
pending.each do |name|
|
1154
|
-
update_selection(result, sel, name, true)
|
1155
|
-
end
|
1156
|
-
true
|
1157
|
-
end
|
1158
|
-
end
|
1159
|
-
|
1160
1126
|
return result, nonresolved
|
1161
1127
|
end
|
1162
1128
|
|
@@ -1197,38 +1163,20 @@ def compute_revdeps
|
|
1197
1163
|
result
|
1198
1164
|
end
|
1199
1165
|
|
1200
|
-
#
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
def reuse(*dir)
|
1206
|
-
dir = File.expand_path(File.join(*dir), Autoproj.root_dir)
|
1207
|
-
if reused_installations.any? { |mnf| mnf.path == dir }
|
1166
|
+
# Declare that we should reuse the autoproj installation present at the
|
1167
|
+
# given path
|
1168
|
+
def reuse(workspace_root)
|
1169
|
+
if reused_installations.any? { |mnf| mnf.path == workspace_root }
|
1208
1170
|
return
|
1209
1171
|
end
|
1210
1172
|
|
1211
|
-
manifest = InstallationManifest.
|
1212
|
-
if !File.file?(manifest.default_manifest_path)
|
1213
|
-
raise ConfigError.new, "while setting up reuse of #{dir}, the .autoproj-installation-manifest file does not exist. You should probably rerun autoproj envsh in that folder first"
|
1214
|
-
end
|
1173
|
+
manifest = InstallationManifest.from_workspace_root(workspace_root)
|
1215
1174
|
manifest.load
|
1216
1175
|
@reused_installations << manifest
|
1217
1176
|
manifest.each do |pkg|
|
1218
1177
|
ignore_package pkg.name
|
1219
1178
|
end
|
1220
1179
|
end
|
1221
|
-
|
1222
|
-
# Load OS dependency information contained in our registered package
|
1223
|
-
# sets into the provided osdep object
|
1224
|
-
#
|
1225
|
-
# @param [OSPackageResolver] osdeps the osdep handling object
|
1226
|
-
# @return [void]
|
1227
|
-
def load_osdeps_from_package_sets(osdeps)
|
1228
|
-
each_package_set do |pkg_set, file|
|
1229
|
-
osdeps.merge(pkg_set.load_osdeps(file))
|
1230
|
-
end
|
1231
|
-
end
|
1232
1180
|
end
|
1233
1181
|
|
1234
1182
|
def self.manifest
|
@@ -1246,9 +1194,6 @@ def self.osdeps
|
|
1246
1194
|
end
|
1247
1195
|
|
1248
1196
|
def self.config
|
1249
|
-
Autoproj.warn_deprecated(
|
1250
|
-
__method__, "use workspace.config instead")
|
1251
|
-
|
1252
1197
|
workspace.config
|
1253
1198
|
end
|
1254
1199
|
|