Class: Toys::Tool

Inherits:
Object
  • Object
show all
Defined in:
lib/toys/tool.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, name) ⇒ Tool

Returns a new instance of Tool.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/toys/tool.rb', line 7

def initialize(parent, name)
  @parent = parent
  @simple_name = name
  @full_name = name ? [name] : []
  @full_name = parent.full_name + @full_name if parent

  @definition_path = nil
  @cur_path = nil

  @alias_target = nil

  @long_desc = nil
  @short_desc = nil

  @default_data = {}
  @switches = []
  @required_args = []
  @optional_args = []
  @remaining_args = nil
  @helpers = {}
  @modules = []
  @executor = nil

  @defined_modules = {}
end

Instance Attribute Details

#full_nameObject (readonly)

Returns the value of attribute full_name.



34
35
36
# File 'lib/toys/tool.rb', line 34

def full_name
  @full_name
end

#simple_nameObject (readonly)

Returns the value of attribute simple_name.



33
34
35
# File 'lib/toys/tool.rb', line 33

def simple_name
  @simple_name
end

Instance Method Details

#add_helper(name, &block) ⇒ Object



141
142
143
144
145
146
147
148
# File 'lib/toys/tool.rb', line 141

def add_helper(name, &block)
  check_definition_state(true)
  name_str = name.to_s
  unless name_str =~ /^[a-z]\w+$/
    raise ToolDefinitionError, "Illegal helper name: #{name_str.inspect}"
  end
  @helpers[name.to_sym] = block
end

#add_optional_arg(key, accept: nil, default: nil, doc: nil) ⇒ Object



183
184
185
186
187
# File 'lib/toys/tool.rb', line 183

def add_optional_arg(key, accept: nil, default: nil, doc: nil)
  check_definition_state(true)
  @default_data[key] = default
  @optional_args << [key, accept, Array(doc)]
end

#add_required_arg(key, accept: nil, doc: nil) ⇒ Object



177
178
179
180
181
# File 'lib/toys/tool.rb', line 177

def add_required_arg(key, accept: nil, doc: nil)
  check_definition_state(true)
  @default_data[key] = nil
  @required_args << [key, accept, Array(doc)]
end

#add_switch(key, *switches, accept: nil, default: nil, doc: nil) ⇒ Object



168
169
170
171
172
173
174
175
# File 'lib/toys/tool.rb', line 168

def add_switch(key, *switches, accept: nil, default: nil, doc: nil)
  check_definition_state(true)
  @default_data[key] = default
  switches << "--#{canonical_switch(key)}=VALUE" if switches.empty?
  switches << accept unless accept.nil?
  switches += Array(doc)
  @switches << [key, switches]
end

#define_helper_module(name, &block) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/toys/tool.rb', line 108

def define_helper_module(name, &block)
  if @alias_target
    raise ToolDefinitionError, "Tool #{display_name.inspect} is an alias"
  end
  unless name.is_a?(String)
    raise ToolDefinitionError,
      "Helper module name #{name.inspect} is not a string"
  end
  if @defined_modules.key?(name)
    raise ToolDefinitionError,
      "Helper module #{name.inspect} is already defined"
  end
  mod = Module.new(&block)
  mod.instance_methods.each do |meth|
    name_str = meth.to_s
    unless name_str =~ /^[a-z]\w+$/
      raise ToolDefinitionError,
        "Illegal helper method name: #{name_str.inspect}"
    end
  end
  @defined_modules[name] = mod
end

#defining_from(path) ⇒ Object



67
68
69
70
71
72
73
74
75
76
# File 'lib/toys/tool.rb', line 67

def defining_from(path)
  raise ToolDefinitionError, "Already being defined" if @cur_path
  @cur_path = path
  begin
    yield
  ensure
    @definition_path = @cur_path if has_description? || has_definition?
    @cur_path = nil
  end
end

#display_nameObject



40
41
42
# File 'lib/toys/tool.rb', line 40

def display_name
  full_name.join(" ")
end

#effective_long_descObject



48
49
50
# File 'lib/toys/tool.rb', line 48

def effective_long_desc
  @long_desc || @short_desc || default_desc
end

#effective_short_descObject



44
45
46
# File 'lib/toys/tool.rb', line 44

def effective_short_desc
  @short_desc || default_desc
end

#execute(context, args) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/toys/tool.rb', line 200

def execute(context, args)
  return @alias_target.execute(context, args) if @alias_target
  execution_data = parse_args(args, context.binary_name)
  context = create_child_context(context, args, execution_data)
  if execution_data[:usage_error]
    puts(execution_data[:usage_error])
    puts("")
    show_usage(context, execution_data[:optparse])
    -1
  elsif execution_data[:show_help]
    show_usage(context, execution_data[:optparse],
               recursive: execution_data[:recursive])
    0
  else
    catch(:result) do
      context.instance_eval(&@executor)
      0
    end
  end
end

#executor=(executor) ⇒ Object



195
196
197
198
# File 'lib/toys/tool.rb', line 195

def executor=(executor)
  check_definition_state(true)
  @executor = executor
end

#has_definition?Boolean

Returns:

  • (Boolean)


56
57
58
59
60
61
# File 'lib/toys/tool.rb', line 56

def has_definition?
  !@default_data.empty? || !@switches.empty? ||
    !@required_args.empty? || !@optional_args.empty? ||
    !@remaining_args.nil? || !!@executor ||
    !@helpers.empty? || !@modules.empty?
end

#has_description?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/toys/tool.rb', line 52

def has_description?
  !@long_desc.nil? || !@short_desc.nil?
end

#long_desc=(str) ⇒ Object



136
137
138
139
# File 'lib/toys/tool.rb', line 136

def long_desc=(str)
  check_definition_state
  @long_desc = str
end

#only_collection?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/toys/tool.rb', line 63

def only_collection?
  @executor == false
end

#root?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/toys/tool.rb', line 36

def root?
  @parent.nil?
end

#set_alias_target(target_tool) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/toys/tool.rb', line 88

def set_alias_target(target_tool)
  unless target_tool.is_a?(Toys::Tool)
    raise ArgumentError, "Illegal target type"
  end
  if only_collection?
    raise ToolDefinitionError, "Tool #{display_name.inspect} is already" \
      " a collection and cannot be made an alias"
  end
  if has_description? || has_definition?
    raise ToolDefinitionError, "Tool #{display_name.inspect} already has" \
      " a definition and cannot be made an alias"
  end
  if @executor == false
    raise ToolDefinitionError, "Cannot make tool #{display_name.inspect}" \
      " an alias because a descendant is already executable"
  end
  @parent.ensure_collection_only(full_name) if @parent
  @alias_target = target_tool
end

#set_remaining_args(key, accept: nil, default: [], doc: nil) ⇒ Object



189
190
191
192
193
# File 'lib/toys/tool.rb', line 189

def set_remaining_args(key, accept: nil, default: [], doc: nil)
  check_definition_state(true)
  @default_data[key] = default
  @remaining_args = [key, accept, Array(doc)]
end

#short_desc=(str) ⇒ Object



131
132
133
134
# File 'lib/toys/tool.rb', line 131

def short_desc=(str)
  check_definition_state
  @short_desc = str
end

#use_helper_module(mod) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/toys/tool.rb', line 150

def use_helper_module(mod)
  check_definition_state(true)
  case mod
  when Module
    @modules << mod
  when Symbol
    mod = mod.to_s
    file_name = mod.gsub(/([a-zA-Z])([A-Z])/){ |m| "#{$1}_#{$2.downcase}" }.downcase
    require "toys/helpers/#{file_name}"
    const_name = mod.gsub(/(^|_)([a-zA-Z0-9])/){ |m| $2.upcase }
    @modules << Toys::Helpers.const_get(const_name)
  when String
    @modules << mod
  else
    raise ToolDefinitionError, "Illegal helper module name: #{mod.inspect}"
  end
end

#yield_definitionObject



78
79
80
81
82
83
84
85
86
# File 'lib/toys/tool.rb', line 78

def yield_definition
  saved_path = @cur_path
  @cur_path = nil
  begin
    yield
  ensure
    @cur_path = saved_path
  end
end