Class: ThorEnhance::Autogenerate::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/thor_enhance/autogenerate/command.rb

Constant Summary collapse

COMMAND_ERB =
"#{File.dirname(__FILE__)}/templates/command.rb.erb"
COMMAND_TEMPLATE =
ERB.new(File.read(COMMAND_ERB))
AGGREGATE_OPTIONS_ERB =
"#{File.dirname(__FILE__)}/templates/aggregate_options.rb.erb"
AGGREGATE_OPTIONS_TEMPLATE =
ERB.new(File.read(AGGREGATE_OPTIONS_ERB))
CLASS_OPTIONS_ERB =
"#{File.dirname(__FILE__)}/templates/class_options.rb.erb"
CLASS_OPTIONS_TEMPLATE =
ERB.new(File.read(CLASS_OPTIONS_ERB))
"#{File.dirname(__FILE__)}/templates/footer.rb.erb"
ERB.new(File.read(FOOTER_ERB))

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(leaf:, name:, basename:, root:, parent: nil) ⇒ Command

Returns a new instance of Command.



24
25
26
27
28
29
30
31
32
# File 'lib/thor_enhance/autogenerate/command.rb', line 24

def initialize(leaf:, name:, basename:, root: , parent: nil)
  @leaf = leaf
  @name = name
  @basename = basename
  @child_commands = []
  @parent = parent
  @root = root
  initialize_children!
end

Instance Attribute Details

#basenameObject (readonly)

Returns the value of attribute basename.



22
23
24
# File 'lib/thor_enhance/autogenerate/command.rb', line 22

def basename
  @basename
end

#child_commandsObject (readonly)

Returns the value of attribute child_commands.



22
23
24
# File 'lib/thor_enhance/autogenerate/command.rb', line 22

def child_commands
  @child_commands
end

#leafObject (readonly)

Returns the value of attribute leaf.



22
23
24
# File 'lib/thor_enhance/autogenerate/command.rb', line 22

def leaf
  @leaf
end

#nameObject (readonly)

Returns the value of attribute name.



22
23
24
# File 'lib/thor_enhance/autogenerate/command.rb', line 22

def name
  @name
end

#parentObject (readonly)

Returns the value of attribute parent.



22
23
24
# File 'lib/thor_enhance/autogenerate/command.rb', line 22

def parent
  @parent
end

#rootObject (readonly)

Returns the value of attribute root.



22
23
24
# File 'lib/thor_enhance/autogenerate/command.rb', line 22

def root
  @root
end

Instance Method Details

#all_basesObject



149
150
151
# File 'lib/thor_enhance/autogenerate/command.rb', line 149

def all_bases
  [default_command_string, basename_string].compact
end

#basename_stringObject



141
142
143
# File 'lib/thor_enhance/autogenerate/command.rb', line 141

def basename_string
   "#{parent_basename_string} #{command.usage}"
end

#class_optionsObject



135
136
137
138
139
# File 'lib/thor_enhance/autogenerate/command.rb', line 135

def class_options
  leaf.base.class_options.map do |name, class_option|
    class_option.hide ? nil : Option.new(name: name, option: class_option)
  end.compact
end

#class_options_erbObject



125
126
127
128
129
130
131
132
133
# File 'lib/thor_enhance/autogenerate/command.rb', line 125

def class_options_erb
  @class_options_erb ||= begin
    if class_options.empty?
      nil
    else
      CLASS_OPTIONS_TEMPLATE.result_with_hash({ method_options_text_array: class_options.map(&:template_text) })
    end
  end
end

#command_erbObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/thor_enhance/autogenerate/command.rb', line 54

def command_erb
  @command_erb ||= begin
    params = {
      all_bases: all_bases,
      basename_string: basename_string,
      children_descriptors: children_descriptors,
      class_options_erb: class_options_erb,
      command: command,
      command_source: command_source,
      custom_headers: custom_headers,
      default_command: default_command,
      default_command_string: default_command_string,
      description: description,
      drawn_out_examples: drawn_out_examples,
      footer_erb: footer_erb,
      headers: headers,
      method_options_erb: method_options_erb,
      parent_basename_string: parent_basename_string,
      preferred_basename_string: preferred_basename_string,
      title: title,
    }
    COMMAND_TEMPLATE.result_with_hash(params)
  end
end

#command_sourceObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/thor_enhance/autogenerate/command.rb', line 79

def command_source
  # if children exists, it is a subcommand
  # source location for a command does not accurately find the correct source
  # Return nil and skip output
  return nil if children?

  file, line = leaf.base.instance_method(name).source_location
  # This value returns the length of the root up to generated_readme
  # This allows us to understand how many directories to remove from the local `source_location`
  remove_length = root.split("/")[0..-2].length

  # this will return the relative location of the command source line
  relative_source = file.split("/")[remove_length..-1]
  relative_link = "/#{relative_source.join("/")}#L#{line}"
  "Source code for this command can be found at: [#{leaf.base.name}##{name}](#{relative_link})"
end

#default_commandObject



226
227
228
229
230
231
232
233
234
# File 'lib/thor_enhance/autogenerate/command.rb', line 226

def default_command
  if children?
    leaf.base.subcommand_classes[name].default_task
  else
    leaf.base.default_task
  end
rescue
  nil
end

#default_command_stringObject



145
146
147
# File 'lib/thor_enhance/autogenerate/command.rb', line 145

def default_command_string
  parent_basename_string if name == default_command
end

#descriptionObject



214
215
216
# File 'lib/thor_enhance/autogenerate/command.rb', line 214

def description
  command.long_description || command.description
end

#drawn_out_examples(with_desc: true) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/thor_enhance/autogenerate/command.rb', line 103

def drawn_out_examples(with_desc: true)
  case command.example
  when nil
  when Array
    command.example.map do |example|
      value = []
      value << "# #{example[:arguments][:kwargs][:desc]}" if with_desc
      value << "#{parent_basename_string} #{example[:input]}"
      value.join("\n")
    end
  else
    value = []
    value << "# #{example[:arguments][:kwargs][:desc]}" if with_desc
    value << "#{parent_basename_string} #{example[:input]}"
    [value.join("\n")]
  end
end

#flatten_childrenObject

this only returns children and its children Call this on top most parent to retreive family tree for subcommands



188
189
190
191
192
193
194
# File 'lib/thor_enhance/autogenerate/command.rb', line 188

def flatten_children
  return [] if child_commands.empty?

  child_commands.map do |child|
    [child, child.flatten_children]
  end.flatten
end


96
97
98
99
100
101
# File 'lib/thor_enhance/autogenerate/command.rb', line 96

def footer_erb
  @footer_erb ||=  begin
    regenerate_thor_command = "#{basename} thor_enhance_autogenerate --apply"
    FOOTER_TEMPLATE.result_with_hash({ regenerate_thor_command: regenerate_thor_command })
  end
end

#initialize_children!Object



34
35
36
37
38
39
40
# File 'lib/thor_enhance/autogenerate/command.rb', line 34

def initialize_children!
  return unless children?

  @child_commands = leaf.children.map do |name, child_leaf|
    self.class.new(root: root, leaf: child_leaf, name: name, basename: basename, parent: self)
  end
end

#method_optionsObject



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/thor_enhance/autogenerate/command.rb', line 42

def method_options
  @method_options ||= begin
    _options = options.map { |name, option| Option.new(name: name, option: option) }
    _options = _options.group_by { _1.readme_type }
    unless _options.empty?
      _options.delete(ThorEnhance.configuration.autogenerated_config.readme_skip_key)
    end

    _options
  end
end

#method_options_erbObject



121
122
123
# File 'lib/thor_enhance/autogenerate/command.rb', line 121

def method_options_erb
  @method_options_erb ||= AGGREGATE_OPTIONS_TEMPLATE.result_with_hash({ method_options: method_options })
end

#parent_basename_stringObject



157
158
159
160
161
162
163
164
165
# File 'lib/thor_enhance/autogenerate/command.rb', line 157

def parent_basename_string
  parent_names = [basename]
  temp_leaf = leaf
  while parent = temp_leaf.parent
    temp_leaf = parent
    parent_names << parent.command.usage
  end
  parent_names.join(" ")
end

#parent_rootObject



167
168
169
170
171
172
173
174
175
# File 'lib/thor_enhance/autogenerate/command.rb', line 167

def parent_root
  if parent
    # Remove the last index of parent because that will be the Readme.md file
    # We just want the directory of the parent file
    parent.relative_readme_path[0..-2]
  else
    []
  end
end

#preferred_basename_stringObject



153
154
155
# File 'lib/thor_enhance/autogenerate/command.rb', line 153

def preferred_basename_string
  default_command_string || basename_string
end

#relative_readme_pathObject



177
178
179
180
181
182
183
184
# File 'lib/thor_enhance/autogenerate/command.rb', line 177

def relative_readme_path
  if children?
    # If children exist, this is a subcommand and needs to be a root ReadMe
    [*parent_root, name, "Readme.md"]
  else
    [*parent_root, "#{name}.md"]
  end
end

#save_self!(root:, apply:) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/thor_enhance/autogenerate/command.rb', line 196

def save_self!(root:, apply:)
  absolute_path = "#{root}/#{relative_readme_path.join("/")}"
  pathname = Pathname.new(absolute_path)
  FileUtils.mkdir_p(pathname.dirname)
  if File.exist?(absolute_path)
    content = File.read(absolute_path)
    diff = command_erb == content ? :same : :overwite
  else
    diff = :new
  end

  if apply
    File.write(absolute_path, command_erb)
  end

  { path: absolute_path, diff: diff, apply: apply, self_for_root: self_for_root }
end

#self_for_rootObject



222
223
224
# File 'lib/thor_enhance/autogenerate/command.rb', line 222

def self_for_root
  params_for_child(self)
end

#titleObject



218
219
220
# File 'lib/thor_enhance/autogenerate/command.rb', line 218

def title
  command.title&.dig(:input) || command.usage
end