Module: Etna::CommandOrExecutor

Included in:
Command
Defined in:
lib/etna/command.rb

Overview

Provides the usage DSL and method that includes information about a CommandExecutor or a Command. Commands or CommandExecutors can call ‘usage’ in their definition to provide a specific description to be given about that command. By default, the command name + desc method will be shown.

Defined Under Namespace

Modules: Dsl

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(cls) ⇒ Object



155
156
157
# File 'lib/etna/command.rb', line 155

def self.included(cls)
  cls.extend(Dsl)
end

Instance Method Details

#command_nameObject



100
101
102
# File 'lib/etna/command.rb', line 100

def command_name
  self.class.name.snake_case.split(/::/).last
end

#completions_for(parameter) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/etna/command.rb', line 92

def completions_for(parameter)
  if parameter == 'env' || parameter == 'environment' || parameter =~ /_env/
    ['production', 'staging', 'development']
  else
    ["__#{parameter}__"]
  end
end

#descObject

By default, the description of a command maps the execute parameters into CLI descriptions, where as CommandExecutors will display their subcommands.



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/etna/command.rb', line 125

def desc
  if respond_to?(:execute)
    method(:execute).parameters.map do |type, name|
      name = "..." if name.nil?

      case type
      when :req
        "<#{name}>"
      when :opt
        "[<#{name}>]"
      when :rest
        "<#{name}>..."
      when :keyrest
        "[flags...]"
      when :key, :keyreq
        flag = "--#{name.to_s.gsub('_', '-')}"
        if self.class.boolean_flags.include?(flag)
          "[#{flag}]"
        else
          "[#{flag} <#{name}>]"
        end
      else
        raise "Invalid command execute argument specification #{type}, unsure how to format description."
      end
    end.join(' ')
  elsif respond_to?(:subcommands)
    '<command> <args>...'
  end
end

#flag_argspecObject



108
109
110
# File 'lib/etna/command.rb', line 108

def flag_argspec
  @argspec ||= []
end

#flag_as_parameter(flag) ⇒ Object



48
49
50
# File 'lib/etna/command.rb', line 48

def flag_as_parameter(flag)
  flag.gsub('--', '').gsub('-', '_')
end

#parse_flags(*args) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/etna/command.rb', line 52

def parse_flags(*args)
  new_args = []
  flags = {}
  found_non_flag = false

  until args.empty?
    next_arg = args.shift

    unless next_arg.start_with? '--'
      new_args << next_arg
      found_non_flag = true
      next
    end

    arg_name = flag_as_parameter(next_arg).to_sym

    if self.class.boolean_flags.include?(next_arg)
      flags[arg_name] = true
    elsif self.class.string_flags.include?(next_arg)
      if args.empty?
        raise "flag #{next_arg} requires an argument"
      else
        flags[arg_name] = args.shift
      end
    elsif self.class.multi_flags.include?(next_arg)
      if args.empty?
        raise "flag #{next_arg} requires an argument"
      else
        (flags[arg_name] ||= []) << args.shift
      end
    elsif !found_non_flag
      raise "#{program_name} does not recognize flag #{next_arg}"
    else
      new_args << next_arg
    end
  end

  [flags, new_args]
end

#program_nameObject

Program name is used to compose the usage display. The top level executor will just assume the running process’s bin name, while other executors will use the ‘command name’ of the Command / Exectuor (class name derived) and whatever program_name exists for its parent scope.



115
116
117
118
119
120
121
# File 'lib/etna/command.rb', line 115

def program_name
  if parent.nil? || !parent.respond_to?(:program_name)
    $PROGRAM_NAME
  else
    parent.program_name + " " + command_name
  end
end

#usageObject



104
105
106
# File 'lib/etna/command.rb', line 104

def usage
  "  #{"%-45s" % command_name}#{desc}"
end