Module: Roby::CLI::Gen::Helpers

Included in:
Roby::CLI::Gen
Defined in:
lib/roby/cli/gen/helpers.rb

Overview

Helper methods for generator actions and templates

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

Defined Under Namespace

Classes: Base, Context

Instance Method Summary collapse

Instance Method Details

#in_module(*module_path) ⇒ (String,String,String)

Helper to handle opening and closing modules

Examples:

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 %>

Returns:

  • ((String,String,String))

    the indentation string for the module’s content, the code necessary to open the module and the code to close it



162
163
164
165
166
167
168
169
170
171
172
# 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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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



144
145
146
# File 'lib/roby/cli/gen/helpers.rb', line 144

def make_context(vars)
    Context.new(vars).context
end

#pathize(string) ⇒ Object

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'


181
182
183
184
185
186
187
188
189
190
# 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) ⇒ Object

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

Both paths are returned relative to the given roots

Examples:

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

Raises:

  • InconsistenName if parts of the given name are inconsistent with the given roots



29
30
31
32
33
34
35
# 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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Helper for #resolve_name



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# 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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Helper for #resolve_name



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# 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