Class: Autoproj::PackageSelection

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/autoproj/package_selection.rb

Overview

Class holding information about which packages have been selected, and why. It is used to decide whether some non-availability of packages are errors or simply warnings (i.e. if the user really wants a given package, or merely might be adding it by accident)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePackageSelection

Returns a new instance of PackageSelection.



35
36
37
38
39
40
41
42
43
# File 'lib/autoproj/package_selection.rb', line 35

def initialize
    @selection = Hash.new { |h, k| h[k] = Set.new }
    @matches = Hash.new { |h, k| h[k] = Set.new }
    @weak_dependencies = Hash.new
    @ignores = Hash.new { |h, k| h[k] = Set.new }
    @exclusions = Hash.new { |h, k| h[k] = Set.new }
    @source_packages = Set.new
    @osdeps = Set.new
end

Instance Attribute Details

#exclusionsObject (readonly)

After a call to #filter_excluded_and_ignored_packages, this contains the set of package exclusions that have been ignored because the corresponding metapackage has a weak dependency policy



25
26
27
# File 'lib/autoproj/package_selection.rb', line 25

def exclusions
  @exclusions
end

#ignoresObject (readonly)

After a call to #filter_excluded_and_ignored_packages, this contains the set of package ignores that have been ignored because the corresponding metapackage has a weak dependency policy



29
30
31
# File 'lib/autoproj/package_selection.rb', line 29

def ignores
  @ignores
end

#matchesObject (readonly)

The set of matches, i.e. a mapping from a user-provided string to the set of packages it selected



11
12
13
# File 'lib/autoproj/package_selection.rb', line 11

def matches
  @matches
end

#osdepsObject (readonly)

The set of osdeps that have been selected



33
34
35
# File 'lib/autoproj/package_selection.rb', line 33

def osdeps
  @osdeps
end

#selectionObject (readonly)

The set of selected packages, as a hash of the package name to the set of user-provided strings that caused that package to be selected



15
16
17
# File 'lib/autoproj/package_selection.rb', line 15

def selection
  @selection
end

#source_packagesObject (readonly)

The set of source packages that have been selected



31
32
33
# File 'lib/autoproj/package_selection.rb', line 31

def source_packages
  @source_packages
end

#weak_dependenciesObject (readonly)

A flag that tells #filter_excluded_and_ignored_packages whether the a given package selection is weak or not.

If true, a selection that have some excluded packages will not generate an error. Otherwise (the default), an error is generated



21
22
23
# File 'lib/autoproj/package_selection.rb', line 21

def weak_dependencies
  @weak_dependencies
end

Instance Method Details

#all_selected_osdep_packages(manifest) ⇒ Array<String>

Returns the source packages selected explicitely or through dependencies

Parameters:

Returns:

  • (Array<String>)


92
93
94
95
96
97
98
# File 'lib/autoproj/package_selection.rb', line 92

def all_selected_osdep_packages(manifest)
    all_sources = all_selected_source_packages(manifest)
    from_source = all_sources.each_with_object(Set.new) do |pkg, s|
        s.merge(pkg.autobuild.os_packages)
    end
    from_source | osdeps
end

#all_selected_source_packages(manifest) ⇒ Array<PackageDefinition>

Returns the source packages selected explicitely or through dependencies

Parameters:

Returns:



76
77
78
79
80
81
82
83
84
85
# File 'lib/autoproj/package_selection.rb', line 76

def all_selected_source_packages(manifest)
    names = Set.new
    roots = each_source_package_name.to_set
    roots.each do |pkg_name|
        manifest.find_autobuild_package(pkg_name).all_dependencies(names)
    end
    names.merge(roots).map do |pkg_name|
        manifest.find_package_definition(pkg_name)
    end
end

#each(&block) ⇒ Object



100
101
102
103
# File 'lib/autoproj/package_selection.rb', line 100

def each(&block)
    Autoproj.warn_deprecated "PackageSelection#each", "use PackageSelection#each_source_package_name instead", 0
    each_source_package_name(&block)
end

#each_osdep_package_name(&block) ⇒ Object



120
121
122
# File 'lib/autoproj/package_selection.rb', line 120

def each_osdep_package_name(&block)
    osdeps.each(&block)
end

#each_package_name(&block) ⇒ Object



105
106
107
108
109
110
# File 'lib/autoproj/package_selection.rb', line 105

def each_package_name(&block)
    return enum_for(__method__) unless block

    each_source_package_name(&block)
    each_osdep_package_name(&block)
end

#each_source_package_name(&block) ⇒ Object



116
117
118
# File 'lib/autoproj/package_selection.rb', line 116

def each_source_package_name(&block)
    source_packages.each(&block)
end

#empty?Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/autoproj/package_selection.rb', line 49

def empty?
    selection.empty?
end

#excluded?(pkg_name) ⇒ Bool

Test if a package is in the exclusions list

otherwise

Parameters:

  • pkg_name (String)

    Name of the package

Returns:

  • (Bool)

    true, if package is in the exclusion list, false



67
68
69
# File 'lib/autoproj/package_selection.rb', line 67

def excluded?(pkg_name)
    exclusions.include?(pkg_name)
end

#filter_excluded_and_ignored_packages(manifest) ⇒ Object

Remove packages that are explicitely excluded and/or ignored

Raise an error if an explicit selection expands only to an excluded package, and display a warning for ignored packages



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/autoproj/package_selection.rb', line 172

def filter_excluded_and_ignored_packages(manifest)
    matches.each do |sel, expansion|
        excluded, other = expansion.partition { |pkg_name| manifest.excluded?(pkg_name) }
        ignored,  ok    = other.partition { |pkg_name| manifest.ignored?(pkg_name) }

        if !excluded.empty? && (!weak_dependencies[sel] || (ok.empty? && ignored.empty?))
            exclusions = excluded.map do |pkg_name|
                [pkg_name, manifest.exclusion_reason(pkg_name)]
            end
            base_msg = "#{sel} is selected in the manifest or on the command line"
            if exclusions.size == 1
                reason = exclusions[0][1]
                if sel == exclusions[0][0]
                    raise ExcludedSelection.new(sel), "#{base_msg}, but it is excluded from the build: #{reason}"
                elsif weak_dependencies[sel]
                    raise ExcludedSelection.new(sel), "#{base_msg}, but it expands to #{exclusions.map(&:first).join(', ')}, which is excluded from the build: #{reason}"
                else
                    raise ExcludedSelection.new(sel), "#{base_msg}, but its dependency #{exclusions.map(&:first).join(', ')} is excluded from the build: #{reason}"
                end
            elsif weak_dependencies[sel]
                raise ExcludedSelection.new(sel), "#{base_msg}, but expands to #{exclusions.map(&:first).join(', ')}, and all these packages are excluded from the build:\n  #{exclusions.map { |e_name, e_reason| "#{e_name}: #{e_reason}" }.join("\n  ")}"
            else
                raise ExcludedSelection.new(sel), "#{base_msg}, but it requires #{exclusions.map(&:first).join(', ')}, and all these packages are excluded from the build:\n  #{exclusions.map { |e_name, e_reason| "#{e_name}: #{e_reason}" }.join("\n  ")}"
            end
        else
            self.exclusions[sel] |= excluded.to_set.dup
            ignores[sel] |= ignored.to_set.dup
        end

        excluded = excluded.to_set
        ignored  = ignored.to_set
        expansion.delete_if do |pkg_name|
            ignored.include?(pkg_name) || excluded.include?(pkg_name)
        end
    end

    source_packages.delete_if do |pkg_name|
        manifest.excluded?(pkg_name) || manifest.ignored?(pkg_name)
    end
    osdeps.delete_if do |pkg_name|
        manifest.excluded?(pkg_name) || manifest.ignored?(pkg_name)
    end
    selection.delete_if do |pkg_name, _|
        manifest.excluded?(pkg_name) || manifest.ignored?(pkg_name)
    end
    matches.delete_if do |key, sel|
        sel.empty?
    end
end

#has_match_for?(sel) ⇒ Boolean

Returns:

  • (Boolean)


160
161
162
# File 'lib/autoproj/package_selection.rb', line 160

def has_match_for?(sel)
    matches.has_key?(sel)
end

#ignored?(pkg_name) ⇒ Bool

Test if a package is in the ignore list

otherwise

Parameters:

  • pkg_name (String)

    Name of the package

Returns:

  • (Bool)

    true, if package is in the ignore list, false



58
59
60
# File 'lib/autoproj/package_selection.rb', line 58

def ignored?(pkg_name)
    ignores.include?(pkg_name)
end

#include?(pkg_name) ⇒ Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/autoproj/package_selection.rb', line 45

def include?(pkg_name)
    selection.has_key?(pkg_name)
end

#initialize_copy(old) ⇒ Object



149
150
151
152
153
154
155
156
157
158
# File 'lib/autoproj/package_selection.rb', line 149

def initialize_copy(old)
    old.selection.each do |pkg_name, set|
        @selection[pkg_name] = set.dup
    end
    old.matches.each do |sel, set|
        @matches[sel] = set.dup
    end
    @source_packages = old.source_packages.dup
    @osdeps = old.osdeps.dup
end

#match_for(sel) ⇒ Object



164
165
166
# File 'lib/autoproj/package_selection.rb', line 164

def match_for(sel)
    matches[sel]
end

#packagesObject



124
125
126
127
# File 'lib/autoproj/package_selection.rb', line 124

def packages
    Autoproj.warn_deprecated "PackageSelection#packages", "use PackageSelection#source_packages instead", 0
    source_packages
end

#select(sel, packages, *_backward, weak: false, osdep: false) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/autoproj/package_selection.rb', line 129

def select(sel, packages, *_backward, weak: false, osdep: false)
    unless _backward.empty?
        Autoproj.warn_deprecated "calling PackageSelection#select with a boolean as third argument", "use e.g. weak: true instead", 0
        weak = _backward.first
    end

    packages = Array(packages).to_set
    matches[sel].merge(packages)
    packages.each do |pkg_name|
        selection[pkg_name] << sel
    end
    if osdep
        osdeps.merge(packages)
    else
        source_packages.merge(packages)
    end

    weak_dependencies[sel] = weak
end

#selected_source_package?(pkg) ⇒ Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/autoproj/package_selection.rb', line 112

def selected_source_package?(pkg)
    source_packages.include?(pkg.name)
end