module Roby::CLI::Gen::Helpers

Helper methods for generator actions and templates

The module is used to extend {Gen}. Its methods are usually accessed as singletong methods on {Gen}, e.g. {Gen.resolve_name}.

Public Instance Methods

in_module(*module_path) click to toggle source

Helper to handle opening and closing modules

@return [(String,String,String)] the indentation string for the

module's content, the code necessary to open the module and the
code to close it

@example usually used in e.g. ERB with

<% indent, open, close = Roby::App::GenBase.in_module("A", "Module") %>
<%= open %>
<%= indent %>class MyClass
<%= indent %>    it_does_something
<%= indent %>end
<%= close %>
# File lib/roby/cli/gen/helpers.rb, line 162
def in_module(*module_path)
    indent = ""
    open_code  = []
    close_code = []
    module_path.each do |m|
        open_code.push "#{indent}module #{m}"
        close_code.unshift "#{indent}end"
        indent = indent + "    "
    end
    return indent, open_code.join("\n"), close_code.join("\n")
end
make_context(vars) click to toggle source

@api private

Generate a context that be given to the context: argument to Thor's template action

# File lib/roby/cli/gen/helpers.rb, line 144
def make_context(vars)
    Context.new(vars).context
end
pathize(string) click to toggle source

Converts an input string that is in camelcase into a path string

NOTE: Facets' String#pathize and String#snakecase have corner cases that really don't work for us:

'2D'.snakecase => '2_d'
'GPS'.pathize => 'gp_s'
# File lib/roby/cli/gen/helpers.rb, line 181
def pathize(string)
    string.
        gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
        gsub(/([a-z])([A-Z][a-z])/,'\1_\2').
        gsub('__','/').
        gsub('::','/').
        gsub(/\s+/, '').                # spaces are bad form
        gsub(/[?%*:|"<>.]+/, '').   # reserved characters
        downcase
end
resolve_name(gen_type, given_name, robot_name, file_root, namespace_root) click to toggle source

Resolve a user-given model name into the corresponding file path and namespace path

Both paths are returned relative to the given roots

@raise InconsistenName if parts of the given name are inconsistent with the given

roots

@example

resolve_names('models/actions/navigation.rb',
              ['models', 'actions'],
              ['Actions']) # => [['navigation.rb'], ['Navigation']]
resolve_names('models/tasks/navigation/goto.rb',
              ['models', 'tasks'],
              ['Tasks']) # => [['navigation/goto.rb'], ['Navigation', 'Goto']]
resolve_names('models/tasks/navigation/goto.rb',
              ['models', 'actions'],
              ['Actions']) # => raise, as models/actions must be the path root
# File lib/roby/cli/gen/helpers.rb, line 29
def resolve_name(gen_type, given_name, robot_name, file_root, namespace_root)
    if given_name =~ /\// || given_name[0, 1] !~ /[A-Z]/
        resolve_name_as_path(gen_type, given_name, robot_name, file_root, namespace_root)
    else
        resolve_name_as_constant(gen_type, given_name, robot_name, file_root, namespace_root)
    end
end
resolve_name_as_constant(gen_type, given_name, robot_name, file_root, namespace_root) click to toggle source

@api private

Helper for {#resolve_name}

# File lib/roby/cli/gen/helpers.rb, line 78
def resolve_name_as_constant(gen_type, given_name, robot_name, file_root, namespace_root)
    robot_module =
        if robot_name
            [robot_name.camelcase(:upper)]
        else
            []
        end

    given_class_name = given_name.split("::")
    app_module_name = Roby.app.module_name.split("::")
    full_namespace_root = app_module_name + namespace_root

    non_matching_full_prefix = full_namespace_root.each_with_index.find do |p, i|
        given_class_name[i] != p
    end
    if non_matching_full_prefix
        if non_matching_full_prefix[1] != 0
            raise CLIInvalidArguments, "attempted to create a #{gen_type} model outside of its expected namespace #{full_namespace_root.join("::")}"
        else
            non_matching_app_prefix = namespace_root.each_with_index.find do |p, i|
                given_class_name[i] != p
            end
            if non_matching_app_prefix
                if non_matching_app_prefix[1] != 0
                    raise CLIInvalidArguments, "attempted to create a #{gen_type} model outside of its expected namespace #{full_namespace_root.join("::")}"
                else
                    given_class_name = full_namespace_root + given_class_name
                end
            else
                given_class_name = app_module_name + given_class_name
            end
        end
    end


    if robot_name && given_class_name[-2, 1] != robot_module
        raise CLIInvalidArguments, "attempted to create a model for robot #{robot_name} outside the expected namespace #{robot_module.join("::")} (e.g. #{given_class_name[0..-2].join("::")}::#{robot_module.join("::")}::#{given_class_name[-1]})"
    end

    file_name = *given_class_name[full_namespace_root.size..-1].map do |camel|
        pathize(camel)
    end
    return file_name, given_class_name
end
resolve_name_as_path(gen_type, given_name, robot_name, file_root, namespace_root) click to toggle source

@api private

Helper for {#resolve_name}

# File lib/roby/cli/gen/helpers.rb, line 40
def resolve_name_as_path(gen_type, given_name, robot_name, file_root, namespace_root)
    robot_module =
        if robot_name
            [robot_name.camelcase(:upper)]
        else
            []
        end

    file_name = given_name.split('/')
    non_matching_prefix = file_root.each_with_index.find do |p, i|
        file_name[i] != p
    end
    if non_matching_prefix
        if non_matching_prefix[1] != 0
            raise CLIInvalidArguments, "attempted to create a #{gen_type} model outside of #{file_root.join("/")}"
        else
            file_name = file_root + file_name
        end
    end

    if robot_name && file_name[-2] != robot_name
        raise CLIInvalidArguments, "attempted to create a model for robot #{robot_name} outside a #{robot_name}/ subfolder"
    end

    file_name[-1] = File.basename(file_name[-1], '.rb')
    file_name_without_root = file_name[file_root.size..-1]

    app_module_name = Roby.app.module_name.split("::")
    class_without_app =
        namespace_root +
        file_name_without_root.map { |n| n.camelcase(:upper) }
    class_name = app_module_name + class_without_app
    return file_name_without_root, class_name
end