Module: Subcommands

Included in:
GitScribe
Defined in:
lib/subcommand.rb

Instance Method Summary collapse

Instance Method Details

#_check_alias(cmd) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/subcommand.rb', line 205

def _check_alias cmd
  alas = @aliases[cmd]
  #$stderr.puts "195 alas: #{alas} "
  if alas
    case alas
    when Array
      cmd = alas.shift
      #$stderr.puts "Array cmd: #{cmd} "
      ARGV.unshift alas.shift unless alas.empty?
      #$stderr.puts "ARGV  #{ARGV} "
    else
      cmd = alas
    end
  end
  sc = @commands[cmd] if cmd
  return sc, cmd
end

#add_help_optionObject

this is so that on pressing –help he gets same subcommand help as when doing help. This is to be added in your main program, after defining global options if you want detailed help on –help. This is since optionparser’s default –help will not print your actions/commands



126
127
128
129
130
131
132
133
134
# File 'lib/subcommand.rb', line 126

def add_help_option
  global_options do |opts|
    opts.on("-h", "--help", "Print this help") do |v|
      add_subcommand_help
      puts @global
      exit
    end
  end
end

#add_subcommand_helpObject

add text of subcommands in help and –help option



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/subcommand.rb', line 110

def add_subcommand_help
  # user has defined some, but lets add subcommand information

  cmdtext = print_actions

  global_options do |opts|
    # lets add the description user gave into banner
    opts.banner << "\n#{opts.description}\n" if opts.description
    opts.separator ""
    opts.separator cmdtext
  end
end

#alias_command(name, *args) ⇒ Object



202
203
204
# File 'lib/subcommand.rb', line 202

def alias_command name, *args
  @aliases[name.to_s] = args
end

#command(*names) ⇒ Object

specify a single command and all its options If multiple names are given, they are treated as aliases. Do repeatedly for each command Yields the optionparser



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/subcommand.rb', line 64

def command *names
  name = names.shift
  @commands ||= {}
  @aliases ||= {}
  if names.length > 0
    names.each do |n| 
      #puts "aliases #{n} => #{name} "
      @aliases[n.to_s] = name.to_s
    end
  end
  # Thanks to Robert Klemme for the lazy loading idea.
  opt = lambda { OptionParser.new do |opts|
    yield opts
    # append desc to banner in next line
    opts.banner << "\n#{opts.description}\n" if opts.description
  end }
  @commands[name.to_s] = opt
end

#global_optionsObject

specify global options and banner and description Yields the optionparser



84
85
86
87
88
89
90
91
92
# File 'lib/subcommand.rb', line 84

def global_options
  if !defined? @global
    @global = OptionParser.new do |opts|
      yield opts
    end
  else
    yield @global
  end
end

#opt_parseObject

first parse global optinos then parse subcommand options if valid subcommand special case of “help command” so we print help of command - git style (3) in all invalid cases print global help

Returns:

  • command name if relevant



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/subcommand.rb', line 140

def opt_parse
  # if user has not defined global, we need to create it
  @command_name = nil
  if !defined? @global
    global_options do |opts|
      opts.banner = "Usage: #{$0} [options] [subcommand [options]]"
      opts.separator ""
      opts.separator "Global options are:"
      opts.on("-h", "--help", "Print this help") do |v|
        add_subcommand_help
        puts @global
        exit
      end
      opts.separator ""
      #opts.separator subtext # FIXME: no such variable supposed to have subcommand help
    end
  else
  end
  @global.order!
  cmd = ARGV.shift
  if cmd
    #$stderr.puts "Command: #{cmd}, args:#{ARGV}, #{@commands.keys} "
    sc = @commands[cmd] 
    #puts "sc: #{sc}: #{@commands}"
    unless sc
      # see if an alias exists
      sc, cmd = _check_alias cmd
    end
    # if valid command parse the args
    if sc
      @command_name = cmd
      sc.call.order!
    else
      # else if help <command> then print its help GIT style (3)
      if !ARGV.empty? && cmd == "help"
        cmd = ARGV.shift
        #$stderr.puts " 110 help #{cmd}"
        sc = @commands[cmd]
        # if valid command print help, else print global help
        unless sc
          sc, cmd = _check_alias cmd
        end
        if sc
          #puts " 111 help #{cmd}"
          puts sc.call
        else 
          # no help for this command XXX check for alias
          puts "Invalid command: #{cmd}."
          add_subcommand_help
          puts @global
        end
      else
        # invalid command 
        puts "Invalid command: #{cmd}" unless cmd == "help"
        add_subcommand_help
        puts @global 
      end
      exit 0
    end
  end
  return @command_name
end


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/subcommand.rb', line 93

def print_actions
  cmdtext = "Commands are:"
  @commands.each_pair do |c, opt| 
    #puts "inside opt.call loop"
    desc = opt.call.description
    cmdtext << "\n   #{c} : #{desc}"
  end

  # print aliases
  unless @aliases.empty?
    cmdtext << "\n\nAliases: \n" 
    @aliases.each_pair { |name, val| cmdtext << "   #{name} - #{val}\n"  }
  end

  cmdtext << "\n\nSee '#{$0} help COMMAND' for more information on a specific command."
end