Class: Orocos::ConfigurationManager

Inherits:
Object
  • Object
show all
Extended by:
Logger::Forward, Logger::Hierarchy
Defined in:
lib/orocos/configurations.rb

Overview

Class that manages a set of configurations

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(loader = Orocos.default_loader) ⇒ ConfigurationManager

Returns a new instance of ConfigurationManager.


987
988
989
990
# File 'lib/orocos/configurations.rb', line 987

def initialize(loader = Orocos.default_loader)
    @loader = loader
    @conf   = Hash.new
end

Instance Attribute Details

#conf{String=>TaskConfigurations} (readonly)

A mapping from the task model names to the corresponding TaskConfigurations object

Returns:


985
986
987
# File 'lib/orocos/configurations.rb', line 985

def conf
  @conf
end

#loaderObject (readonly)

Returns the value of attribute loader


979
980
981
# File 'lib/orocos/configurations.rb', line 979

def loader
  @loader
end

Instance Method Details

#apply(task, names = Array.new, options = Hash.new) ⇒ Object

Applies the specified configuration on task

Parameters:

  • options (Hash) (defaults to: Hash.new)

    a customizable set of options

  • task (TaskContext)

    the task on which the configuration should be applied

Options Hash (options):

  • :model_name (String) — default: task.model.name

    the name of the model that should be used to resolve the configurations

  • :override (Boolean) — default: false

    see the documentation of TaskConfigurations#apply


1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
# File 'lib/orocos/configurations.rb', line 1087

def apply(task, names=Array.new, options = Hash.new)
    if options == true || options == false
        # Backward compatibility
        options = Hash[:override => options]
    end
    options, find_options = Kernel.filter_options options, :override => false, :model_name => task.model.name

    model_name = options[:model_name]
    if model_name.nil?
        raise ArgumentError, "applying configuration on #{task.name} failed. #{task.class} has no model name."
    end
    task_conf = find_task_configuration_object(task, find_options.merge(:model_name => model_name))
    if names = resolve_requested_configuration_names(model_name, task_conf, names)
        ConfigurationManager.info "applying configuration #{names.join(", ")} on #{task.name} of type #{model_name}"
        task_conf.apply(task, names, options[:override])
    else
        ConfigurationManager.info "required default configuration on #{task.name} of type #{model_name}, but #{model_name} has no registered configurations"
    end
    true
end

#find_task_configuration_object(task, options = Hash.new) ⇒ Object


1070
1071
1072
1073
1074
1075
1076
# File 'lib/orocos/configurations.rb', line 1070

def find_task_configuration_object(task, options = Hash.new)
    if !task.model
        raise ArgumentError, "cannot use ConfigurationManager#apply for non-orogen tasks"
    end
    options = Kernel.validate_options options, :model_name => task.model.name
    conf[options[:model_name]]
end

#load_dir(dir) ⇒ {String=>Array<String>}

Loads all configuration files present in the given directory

The directory is assumed to be populated with files of the form

orogen_project::TaskName.yml

each file being a YAML file that follows the format described in the documentation of TaskConfigurations. It will ignore files that do not match this pattern, as well as file that refer to task models that cannot be found.

Parameters:

  • dir (String)

    the path to the directory

Returns:

  • ({String=>Array<String>})

    a mapping from the task model name to the list of configuration sections that got modified or added. Note that the set of sections is guaranteed to not be empty


1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
# File 'lib/orocos/configurations.rb', line 1007

def load_dir(dir)
    if !File.directory?(dir)
        raise ArgumentError, "#{dir} is not a directory"
    end

    changed = Hash.new
    Dir.glob(File.join(dir, '*.yml')) do |file|
        next if !File.file?(file)

        changed_configurations =
            begin load_file(file)
            rescue OroGen::TaskModelNotFound
                ConfigurationManager.warn "ignoring configuration file #{file} as there are no corresponding task model"
                next
            end

        if changed_configurations
            changed.merge!(changed_configurations) do |model_name, old, new|
                old.concat(new).uniq
            end

            changed_configurations.each do |model_name, conf|
                ConfigurationManager.info "  configuration #{conf} of #{model_name} changed"
            end
        end
    end
    changed
end

#load_file(file, model = nil) ⇒ {String=>Array<String>}?

Loads configuration from a YAML file

Parameters:

  • file (String)

    the path to the file

  • model (String, OroGen::Spec) (defaults to: nil)

    it is either an oroGen task context model or the name of such a model If nil, the model is inferred from the file name, which is expected to be of the form orogen_project::TaskName.yml

Returns:

  • ({String=>Array<String>}, nil)

    if some configuration sections changed or got added, the method returns a mapping from the task model name to the list of modified sections. Otherwise, it returns false

Raises:

  • ArgumentError if the file does not exist

  • OroGen::TaskModelNotFound if the task model cannot be found


1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
# File 'lib/orocos/configurations.rb', line 1048

def load_file(file, model = nil)
    if !File.file?(file)
        raise ArgumentError, "#{file} does not exist or is not a file"
    end

    if !model || model.respond_to?(:to_str)
        model_name = model || File.basename(file, '.yml')
        model = loader.task_model_from_name(model_name)
    end

    ConfigurationManager.info "loading configuration file #{file} for #{model.name}"
    conf[model.name] ||= TaskConfigurations.new(model)

    changed_configurations = conf[model.name].load_from_yaml(file)
    ConfigurationManager.info "  #{model.name} available configurations: #{conf[model.name].sections.keys.join(", ")}"
    if changed_configurations.empty?
        return false
    else
        Hash[model.name => changed_configurations]
    end
end

#resolve(task_model_name, conf_names = Array.new, override = false) ⇒ Object

Returns a resolved configuration value for a task model name

Parameters:

  • task_model_name (String)

    the name of the task model

  • conf_names (Array<String>) (defaults to: Array.new)

    the name of the configuration sections

  • override (Boolean) (defaults to: false)

    if true, values that are set by early elements in conf_names will be overriden if set in later elements. Otherwise, ArgumentError is thrown when this happens.

Returns:


1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
# File 'lib/orocos/configurations.rb', line 1176

def resolve(task_model_name, conf_names = Array.new, override = false)
    if task_model_name.respond_to?(:model)
        task_model_name = task_model_name.model.name
    end
    task_conf = conf[task_model_name]
    if conf_names = resolve_requested_configuration_names(task_model_name, task_conf, conf_names)
        task_conf.conf(conf_names, override)
    else Hash.new
    end
end

#resolve_requested_configuration_names(model_name, task_conf, names) ⇒ Object


1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
# File 'lib/orocos/configurations.rb', line 1108

def resolve_requested_configuration_names(model_name, task_conf, names)
    if !task_conf
        if names == ['default'] || names == []
            return
        else
            section_name = names.find { |n| n != 'default' }
            raise TaskConfigurations::SectionNotFound.new(section_name), "no configuration available for #{model_name} (expected #{names.join(", ")})"
        end
    end

    # If no names are given try to figure them out 
    if !names || names.empty?
        if(task_conf.sections.size == 1)
            [task_conf.sections.keys.first]
        else
            ["default"]
        end
    else Array(names)
    end
end

#save(task, path, name) ⇒ Object

Saves the configuration for a task and dumps it to a YAML file

This method adds the current configuration of the given task to the existing configuration(s) for the task's model, and saves all of them in a YAML file.

Deprecated.

old signature. One should use the option hash now.

Parameters:

  • task (TaskContext)

    the task whose configuration should be saved

  • path (String)

    the file or directory it should be saved to. If it is a directory, the configuration is saved in a file whose name is based on the task's model name (project_name::TaskName.yml). Otherwise, it is saved in the file. The directories leading to the file must exist.

  • options (Hash) (defaults to: Hash.new)

    a customizable set of options

Options Hash (options):

  • :model (Object) — default: task.model

    the oroGen model used to dump the configuration

  • :name (Object) — default: task.name

    the name of the section that should be created


1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
# File 'lib/orocos/configurations.rb', line 1148

def save(task, path, options = Hash.new)
    if options.respond_to?(:to_str) || !options # for backward compatibility
        options = Hash[:name => options]
    end
    options, find_options = Kernel.filter_options options,
        :name => nil,
        :model => task.model

    model_name = options[:model].name
    task_conf = find_task_configuration_object(task, find_options.merge(:model_name => model_name))
    if !task_conf
        task_conf = conf[model_name] = TaskConfigurations.new(options[:model])
    end
    name = options[:name] || task.name
    task_conf.extract(name, task)
    task_conf.save(name, path, task_model: task.model)
end