class Autoproj::Manifest

The Manifest class represents the information included in the main manifest file, and allows to manipulate it

Constants

PackageSelection

Attributes

accept_unavailable_osdeps[W]

Sets {#accept_unavailable_osdeps?}

automatic_exclusions[R]

A package_name => reason map of the exclusions added with {#exclude_package} Exclusions listed in the manifest file are returned by manifest_exclusions

constant_definitions[R]
data[R]

The manifest data as a Hash

file[R]

The path to the manifest file that has been loaded

ignored_packages[R]

The set of package names for packages that should be ignored

manifest_exclusions[R]

The set of package names that are listed in the excluded_packages section of the manifest

metapackages[R]
moved_packages[R]
normalized_layout[R]

A normalized version of the layout as represented in the manifest file

It is a mapping from a selection name into the layout level it is defined in. For instance:

layout:
- subdir:
  - pkg/in/subdir
- pkg/in/root

Would be normalized as

'pkg/in/subdir' => '/subdir/',
'pkg/in/root' => '/'

Note that these are only strings. There is no normalization against package names or metapackages.

This is computed by {#compute_normalized_layout}

@return [Hash]

os_package_resolver[R]

The definition of all OS packages available on this installation

osdeps_overrides[R]

The set of overrides added with add_osdeps_overrides

package_sets[W]

Set the package sets that are available on this manifest

This is set externally at loading time. {load_and_update_package_sets} can do it as well

@return [Array<PackageSet>]

packages[R]

The set of packages defined so far as a mapping from package name to

Autobuild::Package, package_set, file

tuple

reused_installations[R]

A set of other autoproj installations that are being reused

vcs[RW]

The VCS object for the main configuration itself

@return [VCSDefinition]

Public Class Methods

load(file) click to toggle source

Loads the manifest file located at file and returns the Manifest instance that represents it

# File lib/autoproj/manifest.rb, line 24
def self.load(file)
    manifest = Manifest.new
    manifest.load(file)
    manifest
end
new(ws, os_package_resolver: OSPackageResolver.new) click to toggle source
# File lib/autoproj/manifest.rb, line 188
def initialize(ws, os_package_resolver: OSPackageResolver.new)
    @ws = ws
    @vcs = VCSDefinition.none
    @file = nil
    @data = Hash.new
    @has_layout = false
    @normalized_layout = Hash.new
    @packages = Hash.new
    @package_sets = []
    @os_package_resolver = os_package_resolver
    # Cache for #ignored?
    @ignored_package_names = nil

    @automatic_exclusions = Hash.new
    @constants_definitions = Hash.new
    @moved_packages = Hash.new
    @osdeps_overrides = Hash.new
    @metapackages = Hash.new
    @ignored_os_packages = Set.new
    @reused_installations = Array.new
    @ignored_packages = Set.new
    @manifest_exclusions = Set.new
    @accept_unavailable_osdeps = false

    @constant_definitions = Hash.new
    @package_sets << LocalPackageSet.new(ws)
end

Public Instance Methods

accept_unavailable_osdeps?() click to toggle source

Whether {#resolve_package_name} should raise if an osdep is found that is not available on the current operating system, or simply return it

@return [Boolean]

# File lib/autoproj/manifest.rb, line 163
def accept_unavailable_osdeps?
    !!@accept_unavailable_osdeps
end
add_constant_definition(key, value) click to toggle source

Add a constant definition, used when resolving $CONSTANT in loaded files

# File lib/autoproj/manifest.rb, line 139
def add_constant_definition(key, value)
    constant_definitions[key] = value
end
add_exclusion(package_name, reason) click to toggle source

@deprecated use {#exclude_package} instead

# File lib/autoproj/manifest.rb, line 359
def add_exclusion(package_name, reason)
    Autoproj.warn_deprecated __method__, "use #exclude_package instead"
    exclude_package(package_name, reason)
end
add_metapackage_to_layout(metapackage) click to toggle source

Add a metapackage into the layout

# File lib/autoproj/manifest.rb, line 131
def add_metapackage_to_layout(metapackage)
    validate_metapackage_in_self(metapackage)
    @has_layout = true
    normalized_layout[metapackage.name] = "/"
end
add_osdeps_overrides(osdeps_name, package: osdeps_name, packages: [], force: false) click to toggle source

Declares that autoproj should use normal package(s) to provide the osdeps_name OS package in cases osdeps_name does not exist.

The full syntax is

Autoproj.add_osdeps_overrides 'opencv', :package => 'external/opencv'

If more than one packages should be built, use the :packages option with an array:

Autoproj.add_osdeps_overrides 'opencv', :packages => ['external/opencv', 'external/test']

The :force option allows to force the usage of the source package(s), regardless of the availability of the osdeps package.

# File lib/autoproj/manifest.rb, line 1081
def add_osdeps_overrides(osdeps_name, package: osdeps_name, packages: [], force: false)
    packages << package if package
    packages.each { |pkg_name| resolve_package_name(pkg_name) }
    @osdeps_overrides[osdeps_name.to_s] = Hash[packages: packages, force: force]
end
add_package_set_to_layout(package_set) click to toggle source

Add a package into the layout

# File lib/autoproj/manifest.rb, line 125
def add_package_set_to_layout(package_set)
    validate_package_set_in_self(package_set)
    add_metapackage_to_layout(package_set.metapackage)
end
add_package_to_layout(package) click to toggle source

Add a package into the layout

# File lib/autoproj/manifest.rb, line 118
def add_package_to_layout(package)
    package_name = validate_package_name_argument(package)
    @has_layout = true
    normalized_layout[package_name] = "/"
end
all_layout_packages(validate = true) click to toggle source

Returns the set of package names that are explicitely listed in the layout, minus the excluded and ignored ones

# File lib/autoproj/manifest.rb, line 870
def all_layout_packages(validate = true)
    default_packages(validate)
end
all_package_names() click to toggle source

Returns all defined package names

# File lib/autoproj/manifest.rb, line 875
def all_package_names
    each_autobuild_package.map(&:name)
end
all_selected_osdep_packages(validate = true) click to toggle source

Returns the set of osdep packages that are selected by the layout

@return [Array<String>]

# File lib/autoproj/manifest.rb, line 914
def all_selected_osdep_packages(validate = true)
    default_packages(validate).all_selected_osdep_packages(self)
end
all_selected_packages(validate = true) click to toggle source

Returns the set of packages that are selected by the layout

Unless {#default_packages}, it returns both the selected packages and the dependencies (resolved recursively)

@return [Array<String>] a list of source and osdep package names

# File lib/autoproj/manifest.rb, line 924
def all_selected_packages(validate = true)
    result = Set.new
    selection = default_packages(validate)

    root_sources = selection.each_source_package_name.to_set
    root_sources.each do |pkg_name|
        find_autobuild_package(pkg_name).all_dependencies_with_osdeps(result)
    end
    result | root_sources | selection.each_osdep_package_name.to_set
end
all_selected_source_packages(validate = true) click to toggle source

Returns the set of source packages that are selected by the layout

@return [Array<PackageDefinition>]

# File lib/autoproj/manifest.rb, line 907
def all_selected_source_packages(validate = true)
    default_packages(validate).all_selected_source_packages(self)
end
cache_ignored_package_names() click to toggle source

@api private

The list of packages that are ignored

Do not use directly, use {#ignored?} instead

# File lib/autoproj/manifest.rb, line 283
def cache_ignored_package_names
    return @ignored_package_names if @ignored_package_names

    @ignored_package_names = each_package_definition.find_all do |pkg|
        ignored_packages.any? do |l|
            (pkg.name == l) ||
                ((pkg_set = metapackages[l]) && pkg_set.include?(pkg))
        end
    end.map(&:name).to_set
end
clear_exclusions() click to toggle source

Removes all registered exclusions

# File lib/autoproj/manifest.rb, line 345
def clear_exclusions
    automatic_exclusions.clear
    manifest_exclusions.clear
end
clear_ignored() click to toggle source

Removes all registered ignored packages

# File lib/autoproj/manifest.rb, line 313
def clear_ignored
    invalidate_ignored_package_names
    ignored_packages.clear
end
clear_layout() click to toggle source

Make an empty layout

Unless the default layout (that you can get with {#remove_layout}), this means that no package is selected by default

# File lib/autoproj/manifest.rb, line 103
def clear_layout
    @has_layout = true
    normalized_layout.clear
end
compute_normalized_layout(result, layout_level, layout_data) click to toggle source

@api private

Compute a layout structure that is normalized

# File lib/autoproj/manifest.rb, line 955
def compute_normalized_layout(result, layout_level, layout_data)
    layout_data.each do |value|
        if value.kind_of?(Hash)
            subname, subdef = value.find { true }
            if subdef
                compute_normalized_layout(result, "#{layout_level}#{subname}/", subdef)
            end
        else
            result[value] = layout_level
        end
    end
    result
end
compute_revdeps() click to toggle source

Compute the reverse dependencies of all the packages

The return value is a hash of the form

package_name => [list_of_packages_that_depend_on_package_name]

Where the list is given as a list of package names as well

# File lib/autoproj/manifest.rb, line 1197
def compute_revdeps
    result = Hash.new { |h, k| h[k] = Set.new }
    each_autobuild_package do |pkg|
        pkg.dependencies.each do |pkg_name|
            result[pkg_name] << pkg.name
        end
        pkg.optional_dependencies.each do |pkg_name|
            result[pkg_name] << pkg.name
        end
        pkg.os_packages.each do |pkg_name|
            result[pkg_name] << pkg.name
        end
    end
    result
end
default_packages(validate = true) click to toggle source

Returns the set of packages that should be built if the user does not specify any on the command line

# File lib/autoproj/manifest.rb, line 937
def default_packages(validate = true)
    if has_layout?
        layout_packages(validate)
    else
        result = PackageSelection.new
        all_package_names.each do |pkg_name|
            package_type, package_name = resolve_single_package_name(pkg_name).first
            next if excluded?(package_name) || ignored?(package_name)

            result.select(package_name, package_name, osdep: (package_type == :osdeps))
        end
        result
    end
end
definition_package_set(name) click to toggle source

@deprecated use {#find_package_definition}(pkg_name).package_set instead

# File lib/autoproj/manifest.rb, line 501
def definition_package_set(name)
    Autoproj.warn_deprecated __method__, "use #package_definition_by_name(name).package_set instead"
    package_definition_by_name(name).package_set
end
definition_source(name) click to toggle source

@deprecated use {#find_package_definition}(pkg_name).package_set instead

# File lib/autoproj/manifest.rb, line 494
def definition_source(name)
    Autoproj.warn_deprecated __method__, "use #package_definition_by_name(name).package_set instead"
    package_definition_by_name(name).package_set
end
each_autobuild_package() { |autobuild| ... } click to toggle source

Lists the autobuild objects for all defined packages

@yieldparam [Autobuild::Package] pkg

# File lib/autoproj/manifest.rb, line 543
def each_autobuild_package
    return enum_for(__method__) unless block_given?

    each_package_definition { |pkg| yield(pkg.autobuild) }
end
each_excluded_package() { |pkg| ... } click to toggle source

Enumerates the package names of all ignored packages

# File lib/autoproj/manifest.rb, line 336
def each_excluded_package
    return enum_for(__method__) unless block_given?

    each_autobuild_package do |pkg|
        yield(pkg) if excluded?(pkg.name)
    end
end
each_ignored_package() { |find_autobuild_package(pkg_name)| ... } click to toggle source

Enumerates the package names of all ignored packages

@yieldparam [Autobuild::Package]

# File lib/autoproj/manifest.rb, line 304
def each_ignored_package
    return enum_for(__method__) unless block_given?

    cache_ignored_package_names.each do |pkg_name|
        yield(find_autobuild_package(pkg_name))
    end
end
each_metapackage(&block) click to toggle source

Lists all defined metapackages

Autoproj defines one metapackage per package set, which by default includes all the packages that the package set defines.

# File lib/autoproj/manifest.rb, line 829
def each_metapackage(&block)
    metapackages.each_value(&block)
end
each_package_definition(&block) click to toggle source

Lists all defined packages

@yieldparam [PackageDefinition] pkg

# File lib/autoproj/manifest.rb, line 534
def each_package_definition(&block)
    return enum_for(__method__) unless block_given?

    packages.each_value(&block)
end
each_package_set(&block) click to toggle source

Lists all package sets defined in this manifest, including the package sets that are auto-imported

Note that this can be called only after the package sets got loaded with {load_package_sets}

@yieldparam [PackageSet]

# File lib/autoproj/manifest.rb, line 448
def each_package_set(&block)
    @package_sets.each(&block)
end
each_remote_package_set() { |pkg_set| ... } click to toggle source

Like each_package_set, but filters out local package sets

# File lib/autoproj/manifest.rb, line 433
def each_remote_package_set
    return enum_for(__method__) unless block_given?

    each_package_set do |pkg_set|
        yield(pkg_set) unless pkg_set.local?
    end
end
exclude_package(package_name, reason) click to toggle source

Exclude package_name from the build. reason is a string describing why the package is to be excluded.

# File lib/autoproj/manifest.rb, line 366
def exclude_package(package_name, reason)
    package = validate_package_name_argument(
        package_name, require_existing: false
    )
    if (meta = find_metapackage(package))
        meta.each_package do |pkg|
            automatic_exclusions[pkg.name] =
                "#{meta.name} is an excluded metapackage, "\
                "and it includes #{pkg.name}: #{reason}"
        end
    else
        automatic_exclusions[package] = reason
    end
end
excluded?(package_name) click to toggle source

True if the given package should not be built and its dependencies should be considered as met.

This is useful to avoid building packages that are of no use for the user.

# File lib/autoproj/manifest.rb, line 323
def excluded?(package_name)
    package_name = validate_package_name_argument(package_name)

    if !explicitely_selected_in_layout?(package_name) && excluded_in_manifest?(package_name)
        true
    elsif automatic_exclusions.any? { |pkg_name,| pkg_name == package_name }
        true
    else
        false
    end
end
excluded_in_manifest?(package_name) click to toggle source

Tests whether the given package is excluded in the manifest

# File lib/autoproj/manifest.rb, line 382
def excluded_in_manifest?(package_name)
    package_name = validate_package_name_argument(package_name)
    manifest_exclusions.any? do |matcher|
        if (pkg_set = metapackages[matcher]) && pkg_set.include?(package_name)
            true
        else
            Regexp.new(matcher) === package_name
        end
    end
end
exclusion_reason(package_name) click to toggle source

If package_name is excluded from the build, returns a string that tells why. Otherwise, returns nil

Packages can either be excluded because their name is listed in the exclude_packages section of the manifest, or because they are disabled on this particular operating system.

# File lib/autoproj/manifest.rb, line 399
def exclusion_reason(package_name)
    package_name = validate_package_name_argument(package_name)
    if (message = automatic_exclusions[package_name])
        return message
    end

    unless explicitely_selected_in_layout?(package_name)
        manifest_exclusions.each do |matcher|
            if (pkg_set = metapackages[matcher]) && pkg_set.include?(package_name)
                return "#{pkg_set.name} is a metapackage listed in the exclude_packages section of the manifest, and it includes #{package_name}"
            elsif Regexp.new(matcher) === package_name
                return "#{package_name} is listed in the exclude_packages section of the manifest"
            end
        end
    end
    nil
end
expand_package_selection(selection, filter: true) click to toggle source

Normalizes package selection strings into a PackageSelection object

@param [Array<String>] selection the package selection strings. For

source packages, it can either be the package name, a package set
name, or a prefix of the package's source directory. For osdeps, it
has to be the plain package name

@return [PackageSelection, Array<String>]

# File lib/autoproj/manifest.rb, line 1123
def expand_package_selection(selection, filter: true)
    result = PackageSelection.new

    all_selected_packages = self.all_selected_packages.to_set
    all_source_package_names = all_package_names
    all_osdeps_package_names = os_package_resolver.all_package_names
    selection.each do |sel|
        match_pkg_name = Regexp.new(Regexp.quote(sel))
        all_matches = Array.new
        each_metapackage do |meta_pkg|
            if meta_pkg.name =~ match_pkg_name
                all_matches << [meta_pkg.name, meta_pkg.name == sel]
            end
        end
        all_source_package_names.each do |pkg_name|
            pkg = find_autobuild_package(pkg_name)
            if pkg.name =~ match_pkg_name
                all_matches << [pkg.name, pkg.name == sel]
            elsif "#{sel}/".start_with?("#{pkg.srcdir}/")
                all_matches << [pkg.name, true]
            elsif pkg.respond_to?(:builddir) && "#{sel}/".start_with?("#{pkg.builddir}/")
                all_matches << [pkg.name, true]
            elsif pkg.srcdir.start_with?(sel) && all_selected_packages.include?(pkg.name)
                all_matches << [pkg.name, false]
            end
        end
        all_osdeps_package_names.each do |pkg_name|
            if pkg_name =~ match_pkg_name
                all_matches << [pkg_name, pkg_name == sel]
            end
        end

        exact_matches, partial_matches =
            all_matches.partition { |_, exact_match| exact_match }
        selected_partial_matches, not_selected_partial_matches =
            partial_matches.partition { |pkg_name, _| all_selected_packages.include?(pkg_name) }
        not_selected_partial_matches.clear if result.has_match_for?(sel)

        matches =
            [exact_matches, selected_partial_matches, not_selected_partial_matches]
            .find { |m| !m.empty? }

        matches&.each do |pkg_name, _|
            update_selection(result, sel, pkg_name, true)
        end
    end

    result.filter_excluded_and_ignored_packages(self) if filter

    nonresolved = selection - result.matches.keys
    [result, nonresolved]
end
explicitely_selected_in_layout?(package_name) click to toggle source

Returns true if the given package name has been explicitely added to the layout (not indirectly)

@param [String] package_name @return [Boolean]

# File lib/autoproj/manifest.rb, line 422
def explicitely_selected_in_layout?(package_name)
    package_name = package_name.to_str
    normalized_layout.has_key?(package_name)
end
find_autobuild_package(name) click to toggle source

The autobuild description of a package by its name

@param [String,#name] name the package name @return [Autobuild::Package,nil]

# File lib/autoproj/manifest.rb, line 527
def find_autobuild_package(name)
    find_package_definition(name)&.autobuild
end
find_metapackage(name) click to toggle source
# File lib/autoproj/manifest.rb, line 782
def find_metapackage(name)
    @metapackages[name.to_s]
end
find_package_definition(name) click to toggle source

The autoproj description of a package by its name

@param [String,#name] name the package name @return [PackageDefinition,nil]

# File lib/autoproj/manifest.rb, line 488
def find_package_definition(name)
    packages[validate_package_name_argument(name, require_existing: false)]
end
find_package_set(name) click to toggle source

Returns a package set from its name

# File lib/autoproj/manifest.rb, line 638
def find_package_set(name)
    each_package_set.find { |set| set.name == name }
end
has_package?(name) click to toggle source

Checks if there is a package with a given name

@param [String] name the name of a source or osdep package @return [Boolean]

# File lib/autoproj/manifest.rb, line 628
def has_package?(name)
    packages.has_key?(name) || os_package_resolver.include?(name)
end
has_package_set?(name) click to toggle source

Checks if there is a package set with a given name

# File lib/autoproj/manifest.rb, line 633
def has_package_set?(name)
    !!find_package_set(name)
end
has_remote_package_sets?() click to toggle source

True if some of the sources are remote sources

# File lib/autoproj/manifest.rb, line 428
def has_remote_package_sets?
    each_remote_package_set.any? { true }
end
ignore_package(package) click to toggle source

Call this method to ignore a specific package. It must not be used in init.rb, as the manifest is not yet loaded then

# File lib/autoproj/manifest.rb, line 264
def ignore_package(package)
    invalidate_ignored_package_names
    @ignored_packages << validate_package_name_argument(package, require_existing: false)
end
ignored?(package) click to toggle source

True if the given package should not be built, with the packages that depend on him have this dependency met.

This is useful if the packages are already installed on this system.

# File lib/autoproj/manifest.rb, line 273
def ignored?(package)
    package_name = validate_package_name_argument(package)
    cache_ignored_package_names.include?(package_name)
end
importer_definition_for(package, _package_set = nil, mainline: nil, require_existing: true, package_set: nil) click to toggle source

@overload importer_definition_for(package, mainline: nil, require_existing: true, package_set: nil)

@param [PackageDefinition] package the name of the package to be resolved @param [PackageSet,nil] mainline the reference package set for which

we want to compute the importer definition. Pass package.package_set
if you want to avoid applying any override

@return [VCSDefinition] the VCS definition object

# File lib/autoproj/manifest.rb, line 556
def importer_definition_for(package, _package_set = nil, mainline: nil, require_existing: true, package_set: nil)
    if _package_set
        Autoproj.warn_deprecated "calling #importer_definition_for with the package set as second argument is deprecated, use the package_set: keyword argument instead"
        require_existing = false
    end
    package_name = validate_package_name_argument(package, require_existing: require_existing)
    package_set = _package_set || package_set || package.package_set
    mainline = package_set if mainline == true

    # package_name is already validated, do not re-validate
    vcs = package_set.importer_definition_for(package_name, require_existing: false)

    package_sets = each_package_set.to_a.dup
    index = package_sets.find_index(package_set)
    unless index
        raise RuntimeError, "found inconsistency: package #{package_name} is not in a package set of #{self}"
    end

    return vcs if package_sets[0, index + 1].include?(mainline)

    # Then apply the overrides
    package_sets[(index + 1)..-1].inject(vcs) do |updated_vcs, pkg_set|
        updated_vcs = pkg_set.overrides_for(package_name, updated_vcs, require_existing: false)
        return updated_vcs if pkg_set == mainline

        updated_vcs
    end
end
initialize_from_hash(data) click to toggle source

@api private

Initialize the manifest from a hash, as loaded from a manifest file

# File lib/autoproj/manifest.rb, line 77
def initialize_from_hash(data)
    @data = data
    @ignored_packages |= (data["ignored_packages"] || Set.new).to_set
    @ignored_packages |= (data["ignore_packages"] || Set.new).to_set
    invalidate_ignored_package_names
    @manifest_exclusions |= (data["exclude_packages"] || Set.new).to_set

    normalized_layout = Hash.new
    compute_normalized_layout(
        normalized_layout,
        "/",
        data["layout"] || Hash.new
    )
    @normalized_layout = normalized_layout
    @has_layout = !!data["layout"]

    if data["constants"]
        @constant_definitions =
            Autoproj.resolve_constant_definitions(data["constants"])
    end
end
invalidate_ignored_package_names() click to toggle source

@api private

Invalidate the cache computed by {#cache_ignored_package_names}

# File lib/autoproj/manifest.rb, line 297
def invalidate_ignored_package_names
    @ignored_package_names = nil
end
layout_packages(validate = true) click to toggle source

Returns the packages selected in this manifest’s layout

@return [PackageSelection]

# File lib/autoproj/manifest.rb, line 836
def layout_packages(validate = true)
    result = PackageSelection.new
    Autoproj.in_file(file) do
        normalized_layout.each_key do |pkg_or_set|
            weak =
                if (meta = metapackages[pkg_or_set])
                    meta.weak_dependencies?
                end

            resolve_package_name(pkg_or_set).each do |pkg_type, pkg_name|
                result.select(
                    pkg_or_set, pkg_name,
                    osdep: (pkg_type == :osdeps),
                    weak: weak
                )
            end
        rescue PackageNotFound => e
            raise e, "#{pkg_or_set}, which is selected in the layout, "\
                     "is unknown: #{e.message}", e.backtrace
        end
    end

    begin
        result.filter_excluded_and_ignored_packages(self)
    rescue ExcludedSelection => e
        if validate
            raise e, "#{e.selection}, which is selected in the layout, cannot be built: #{e.message}", e.backtrace
        end
    end
    result
end
load(file) click to toggle source

Load the manifest data contained in file

# File lib/autoproj/manifest.rb, line 54
def load(file)
    unless File.exist?(file)
        raise ConfigError.new(File.dirname(file)),
              "expected an autoproj configuration in #{File.dirname(file)}, "\
              "but #{file} does not exist"
    end

    data = Autoproj.in_file(file, Autoproj::YAML_LOAD_ERROR) do
        YAML.safe_load(File.read(file)) || {}
    end

    if data["layout"]&.member?(nil)
        Autoproj.warn "There is an empty entry in your layout in #{file}. All empty entries are ignored."
        data["layout"] = data["layout"].compact
    end

    @file = file
    initialize_from_hash(data)
end
load_all_available_package_manifests() click to toggle source
# File lib/autoproj/manifest.rb, line 1048
def load_all_available_package_manifests
    # Load the manifest for packages that are already present on the
    # file system
    each_package_definition do |pkg|
        if pkg.checked_out?
            begin
                load_package_manifest(pkg)
            rescue Interrupt
                raise
            rescue Exception => e
                Autoproj.warn "cannot load package manifest for #{pkg.name}: #{e.message}"
            end
        end
    end
end
load_importers(mainline: nil) click to toggle source

Sets up the package importers based on the information listed in the source’s source.yml

The priority logic is that we take the package sets one by one in the order listed in the autoproj main manifest, and first come first used.

A set that defines a particular package in its autobuild file must provide the corresponding VCS line in its source.yml file. However, it is possible for a source that does not define a package to override the VCS

In other words: if package P is defined by source S1, and source S0 imports S1, then

* S1 must have a VCS line for P
* S0 can have a VCS line for P, which would override the one defined
  by S1
# File lib/autoproj/manifest.rb, line 601
def load_importers(mainline: nil)
    packages.each_value do |pkg|
        package_mainline =
            if mainline == true
                pkg.package_set
            else
                mainline
            end
        vcs = importer_definition_for(pkg, mainline: package_mainline)

        if vcs.none?
            if pkg.package_set.importer_definition_for(pkg).none?
                if (pkg.package_set != main_package_set) || !File.exist?(pkg.autobuild.srcdir)
                    raise ConfigError.new, "package set #{pkg.package_set.name} defines the package '#{pkg.name}', but does not provide a version control definition for it"
                end
            end
        end

        pkg.vcs = vcs
        pkg.autobuild.importer = vcs.create_autobuild_importer
    end
end
load_package_manifest(pkg) click to toggle source

Loads the package’s manifest.xml file for the current package

Right now, the absence of a manifest makes autoproj only issue a warning. This will later be changed into an error.

# File lib/autoproj/manifest.rb, line 997
def load_package_manifest(pkg)
    if pkg.respond_to?(:to_str)
        pkg_definition = find_package_definition(pkg)
        unless pkg_definition
            raise ArgumentError, "#{pkg} is not a known package in #{self}"
        end

        pkg = pkg_definition
    end
    package = pkg.autobuild
    package_set = pkg.package_set

    # Look for the package's manifest.xml, but fallback to a manifest in
    # the package set if present
    if package.use_package_xml? && package.checked_out?
        manifest_path = File.join(package.srcdir, "package.xml")
        raise NoPackageXML.new(package.srcdir), "#{package.name} from "\
                                                "#{package_set.name} has use_package_xml set, but the package has "\
                                                "no package.xml file" unless File.file?(manifest_path)

        manifest = PackageManifest.load(package, manifest_path,
                                        ros_manifest: true)
    else
        manifest_paths = [File.join(package.srcdir, "manifest.xml")]
        if package_set.local_dir
            manifest_paths << File.join(
                package_set.local_dir, "manifests", "#{package.name}.xml"
            )
        end
        manifest_path = manifest_paths.find do |path|
            File.file?(path)
        end
        if manifest_path
            manifest = PackageManifest.load(package, manifest_path,
                                            ros_manifest: false)
        end
    end

    if manifest
        pkg.autobuild.description = manifest
    else
        Autoproj.warn "#{package.name} from #{package_set.name} "\
                      "does not have a manifest"
    end

    pkg.apply_dependencies_from_manifest
    # #description is initialized with a null package manifest
    # return it even if we haven't overriden it
    pkg.autobuild.description
end
main_package_set() click to toggle source

The root package set, which represents the workspace itself

# File lib/autoproj/manifest.rb, line 655
def main_package_set
    each_package_set.find(&:main?)
end
metapackage(name, *packages, &block) click to toggle source

Add packages to a metapackage, creating the metapackage if it does not exist

@overload metapackage(name)

Create a metapackage

@return [Metapackage]

@overload metapackage(name, *packages)

Add packages to a new or existing metapackage

@param [String] name the name of the metapackage. If it already
  exists, the packages will be added to it.
@param [String] packages list of package names to be added to the
  metapackage
@return [Metapackage]
# File lib/autoproj/manifest.rb, line 803
def metapackage(name, *packages, &block)
    meta = (@metapackages[name.to_s] ||= Metapackage.new(name))
    packages.each do |arg|
        if !arg.respond_to?(:to_str)
            meta.add(arg)
        elsif (pkg = find_autobuild_package(arg))
            meta.add(pkg)
        elsif (pkg_set = find_metapackage(arg))
            pkg_set.each_package do |pkg_in_set|
                meta.add(pkg_in_set)
            end
        elsif os_package_resolver.has?(arg)
            raise ArgumentError, "cannot specify the osdep #{arg} as an element of a metapackage"
        else
            raise PackageNotFound, "cannot find a package called #{arg}"
        end
    end

    meta.instance_eval(&block) if block
    meta
end
move_package(package_name, new_dir) click to toggle source

Moves the given package name from its current subdirectory to the provided one.

For instance, for a package called drivers/xsens_imu

move("drivers/xsens_imu", "data_acquisition")

will move the package into data_acquisition/xsens_imu

# File lib/autoproj/manifest.rb, line 1186
def move_package(package_name, new_dir)
    moved_packages[package_name] = File.join(new_dir, File.basename(package_name))
end
package(name) click to toggle source

@deprecated use {#find_package_definition} instead

# File lib/autoproj/manifest.rb, line 507
def package(name)
    Autoproj.warn_deprecated "Manifest#package is deprecated, use #package_definition_by_name instead"
    find_package_definition(name)
end
package_definition_by_name(name) click to toggle source

Resolve a package definition by name

Unlike {#find_package_definition}, raise if the package does not exist

# File lib/autoproj/manifest.rb, line 515
def package_definition_by_name(name)
    unless (pkg = find_package_definition(name))
        raise ArgumentError, "no package defined named '#{name}'"
    end

    pkg
end
package_enabled?(name, validate = true) click to toggle source

Returns true if name is a valid package and is included in the build

If validate is true, the method will raise ArgumentError if the package does not exists.

If it is false, the method will simply return false on non-defined packages

# File lib/autoproj/manifest.rb, line 886
def package_enabled?(name, validate = true)
    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."
    true
end
package_selected?(name, validate = true) click to toggle source

Returns true if name is a valid package and is neither excluded from the build, nor ignored from the build

If validate is true, the method will raise ArgumentError if the package does not exists.

If it is false, the method will simply return false on non-defined packages

# File lib/autoproj/manifest.rb, line 899
def package_selected?(name, validate = true)
    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."
    true
end
package_set(name) click to toggle source

The PackageSet object for the given package set

@return [PackageSet] the package set @raise [ArgumentError] if none exists with that name

# File lib/autoproj/manifest.rb, line 646
def package_set(name)
    unless (set = find_package_set(name))
        raise ArgumentError, "no package set called #{name} exists"
    end

    set
end
register_package(package, block = nil, package_set = main_package_set, file = nil) click to toggle source

Register a new package

@param [Autobuild::Package] package @param [#call,nil] block a setup block @param [PackageSet] package_set the package set that defines the package @param [String] file the file in which the package is defined @return [PackageDefinition]

# File lib/autoproj/manifest.rb, line 474
def register_package(package, block = nil, package_set = main_package_set, file = nil)
    invalidate_ignored_package_names
    pkg = PackageDefinition.new(package, package_set, file)
    pkg.add_setup_block(block) if block
    @packages[package.name] = pkg
    metapackage pkg.package_set.name, pkg.autobuild
    metapackage "#{pkg.package_set.name}.all", pkg.autobuild
    pkg
end
register_package_set(pkg_set) click to toggle source

Registers a new package set

@param [PackageSet] pkg_set the package set object

# File lib/autoproj/manifest.rb, line 460
def register_package_set(pkg_set)
    invalidate_ignored_package_names
    metapackage(pkg_set.name)
    metapackage("#{pkg_set.name}.all")
    @package_sets << pkg_set
end
remove_layout() click to toggle source

Remove the layout

Unlike {#clear_layout}, this means that all defined source packages will be selected by default

# File lib/autoproj/manifest.rb, line 112
def remove_layout
    @has_layout = false
    normalized_layout.clear
end
remove_osdeps_overrides(osdep_name) click to toggle source

Remove any OSDeps override that has previously been added with add_osdeps_overrides

# File lib/autoproj/manifest.rb, line 1089
def remove_osdeps_overrides(osdep_name)
    @osdeps_overrides.delete(osdeps_name.to_s)
end
reset_package_sets() click to toggle source

Reset the list of package sets

# File lib/autoproj/manifest.rb, line 453
def reset_package_sets
    @package_sets.clear
end
resolve_package_name(name, include_unavailable: false) click to toggle source

Resolves a name into a set of source and osdep packages

@param [String] name the name to be resolved. It can either be the name of a source package, an osdep package or a metapackage (e.g. package set).

@return [nil,Array] either nil if there is no such osdep, or a list of

(type, package_name) pairs where type is either :package or :osdeps and
package_name the corresponding package name

@raise [PackageNotFound] if the given package name cannot be resolved

into a package. If {#accept_unavailable_osdeps?} is false (the
default), the exception will be raised if the package is known to be
an osdep, but it is not available on the local operating system (as
defined by {#os_package_resolver}), and there has been no source
fallback defined with {#add_osdeps_overrides}. If true, it will
return such a package as an osdep.
# File lib/autoproj/manifest.rb, line 675
def resolve_package_name(name, include_unavailable: false)
    pkg_names =
        if (pkg_set = find_metapackage(name))
            pkg_set.each_package.map(&:name)
        else
            [name.to_str]
        end

    result = []
    pkg_names.each do |pkg|
        result.concat(resolve_single_package_name(pkg))
    rescue PackageUnavailable => e
        if include_unavailable
            result.concat([[:osdeps, pkg]])
        else
            raise e, "cannot resolve #{pkg}: #{e}", e.backtrace
        end
    rescue PackageNotFound => e
        raise e, "cannot resolve #{pkg}: #{e}", e.backtrace
    end
    result
end
resolve_package_name_as_osdep(name) click to toggle source

@api private

Resolve a potential osdep name, either as the osdep itself, or as source packages that are used as osdep override

@return [nil,Array] either nil if there is no such osdep, or a list of

(type, package_name) pairs where type is either :package or :osdep and
package_name the corresponding package name

@raise PackageNotFound if the given package name cannot be resolved

into a package. If {#accept_unavailable_osdeps?} is false (the
default), the exception will be raised if the package is known to be
an osdep, but it is not available on the local operating system (as
defined by {#os_package_resolver}), and there has been no source
fallback defined with {#add_osdeps_overrides}.
If true, it will return it as an osdep.
# File lib/autoproj/manifest.rb, line 753
def resolve_package_name_as_osdep(name)
    osdeps_availability = os_package_resolver.availability_of(name)
    if osdeps_availability == OSPackageResolver::NO_PACKAGE
        raise PackageNotFound, "#{name} is not an osdep"
    end

    # There is an osdep definition for this package, check the
    # overrides
    osdeps_available =
        (osdeps_availability == OSPackageResolver::AVAILABLE) ||
        (osdeps_availability == OSPackageResolver::IGNORE)
    osdeps_overrides = self.osdeps_overrides[name]
    if osdeps_overrides && (!osdeps_available || osdeps_overrides[:force])
        osdeps_overrides[:packages].inject([]) do |result, src_pkg_name|
            result.concat(resolve_package_name_as_source_package(src_pkg_name))
        end.uniq
    elsif !osdeps_available && (pkg = find_autobuild_package(name))
        [[:package, pkg.name]]
    elsif osdeps_available || accept_unavailable_osdeps?
        [[:osdeps, name]]
    elsif osdeps_availability == OSPackageResolver::WRONG_OS
        raise PackageUnavailable, "#{name} is an osdep, but it is not available for this operating system (#{os_package_resolver.operating_system})"
    elsif osdeps_availability == OSPackageResolver::UNKNOWN_OS
        raise PackageUnavailable, "#{name} is an osdep, but the local operating system is unavailable"
    elsif osdeps_availability == OSPackageResolver::NONEXISTENT
        raise PackageUnavailable, "#{name} is an osdep, but it is explicitely marked as 'nonexistent' for this operating system (#{os_package_resolver.operating_system})"
    end
end
resolve_package_name_as_source_package(name) click to toggle source

@api private

Resolve a package name that is assumed to be a source package

@param [String] name the name to be resolved @return [nil,Array] either nil if there is no such osdep, or a list of

(type, package_name) pairs where type is either :package or :osdep and
package_name the corresponding package name

@raise PackageNotFound if the given package name cannot be resolved

into a package
# File lib/autoproj/manifest.rb, line 729
def resolve_package_name_as_source_package(name)
    unless (pkg = find_autobuild_package(name))
        raise PackageNotFound,
              "cannot resolve #{name}: it is neither a package nor an osdep"
    end

    [[:package, pkg.name]]
end
resolve_single_package_name(name) click to toggle source

@api private

Resolves a package name, where name cannot be resolved as a metapackage

This is a helper method for resolve_package_name. Do not use directly

@return [nil,Array] either nil if there is no such osdep, or a list of

(type, package_name) pairs where type is either :package or :osdeps and
package_name the corresponding package name
# File lib/autoproj/manifest.rb, line 709
def resolve_single_package_name(name)
    resolve_package_name_as_osdep(name)
rescue PackageNotFound => osdep_error
    begin
        resolve_package_name_as_source_package(name)
    rescue PackageNotFound
        raise osdep_error, "#{osdep_error} and it cannot be resolved as a source package"
    end
end
reuse(workspace_root) click to toggle source

Declare that we should reuse the autoproj installation present at the given path

# File lib/autoproj/manifest.rb, line 1215
def reuse(workspace_root)
    return if reused_installations.any? { |mnf| mnf.path == workspace_root }

    manifest = InstallationManifest.from_workspace_root(workspace_root)
    manifest.load
    @reused_installations << manifest
    manifest.each do |pkg|
        ignore_package pkg.name
    end
end
update_selection(selection, user_selection_string, name, weak) click to toggle source

@api private

Helper for {#expand_package_selection}

# File lib/autoproj/manifest.rb, line 1098
def update_selection(selection, user_selection_string, name, weak)
    source_packages = Array.new
    osdeps = Array.new
    resolve_package_name(name).each do |type, resolved_name|
        if type == :package
            source_packages << resolved_name
        else
            osdeps << resolved_name
        end
    end
    unless source_packages.empty?
        selection.select(user_selection_string, source_packages, osdep: false, weak: weak)
    end
    unless osdeps.empty?
        selection.select(user_selection_string, osdeps, osdep: true, weak: weak)
    end
end
validate_metapackage_in_self(metapackage) click to toggle source

@api private

Validate that the given metapackage object is defined in self

# File lib/autoproj/manifest.rb, line 219
def validate_metapackage_in_self(metapackage)
    if find_metapackage(metapackage.name) != metapackage
        raise UnregisteredPackage, "#{metapackage.name} is not registered on #{self}"
    end
end
validate_package_in_self(package) click to toggle source

@api private

Validate that the given package object is defined in self

# File lib/autoproj/manifest.rb, line 228
def validate_package_in_self(package)
    if !package.respond_to?(:autobuild)
        raise ArgumentError, "expected a PackageDefinition object but got an Autobuild package"
    elsif find_package_definition(package.name) != package
        raise UnregisteredPackage, "#{package.name} is not registered on #{self}"
    end
end
validate_package_name_argument(package, require_existing: true) click to toggle source

@api private

Massage an argument that should be interpreted as a package name

# File lib/autoproj/manifest.rb, line 239
def validate_package_name_argument(package, require_existing: true)
    if package.respond_to?(:name)
        validate_package_in_self(package)
        package.name
    else
        package = package.to_str
        if require_existing && !has_package?(package)
            raise PackageNotFound, "no package named #{package} in #{self}"
        end

        package
    end
end
validate_package_set_in_self(package_set) click to toggle source

@api private

Validate that the given package object is defined in self

# File lib/autoproj/manifest.rb, line 256
def validate_package_set_in_self(package_set)
    if find_package_set(package_set.name) != package_set
        raise UnregisteredPackageSet, "#{package_set.name} is not registered on #{self}"
    end
end
whereis(package_name) click to toggle source

Returns the level of the layout into which of a certain package would be selected

@return [String]

# File lib/autoproj/manifest.rb, line 973
def whereis(package_name)
    package_name = validate_package_name_argument(package_name)

    matches = [package_name]
    if (source_package = find_package_definition(package_name))
        each_metapackage do |meta|
            matches << meta.name if meta.include?(source_package)
        end
    end

    matches.each do |name|
        if (place = normalized_layout[name])
            return place
        end
    end
    "/"
end