github_cli 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/.travis.yml +14 -3
  2. data/CHANGELOG.md +15 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +41 -44
  5. data/README.md +77 -14
  6. data/Rakefile +4 -2
  7. data/features/assignee.feature +1 -0
  8. data/features/blob.feature +1 -0
  9. data/features/collaborator.feature +1 -0
  10. data/features/commit.feature +2 -1
  11. data/features/config.feature +27 -28
  12. data/features/event.feature +1 -0
  13. data/features/init.feature +20 -23
  14. data/features/key.feature +5 -5
  15. data/features/milestone.feature +3 -2
  16. data/features/reference.feature +3 -2
  17. data/features/starring.feature +1 -0
  18. data/features/support/hooks.rb +1 -1
  19. data/features/tag.feature +2 -1
  20. data/features/tree.feature +17 -0
  21. data/features/watching.feature +1 -0
  22. data/fixtures/simple_config +3 -5
  23. data/github_cli.gemspec +1 -1
  24. data/lib/github_cli/api.rb +11 -6
  25. data/lib/github_cli/apis/event.rb +8 -8
  26. data/lib/github_cli/apis/label.rb +0 -12
  27. data/lib/github_cli/apis/starring.rb +5 -5
  28. data/lib/github_cli/apis/watching.rb +5 -5
  29. data/lib/github_cli/cli.rb +21 -30
  30. data/lib/github_cli/command.rb +1 -1
  31. data/lib/github_cli/commands/authorizations.rb +28 -2
  32. data/lib/github_cli/commands/collaborators.rb +12 -12
  33. data/lib/github_cli/commands/commits.rb +18 -2
  34. data/lib/github_cli/commands/events.rb +6 -8
  35. data/lib/github_cli/commands/followers.rb +1 -1
  36. data/lib/github_cli/commands/labels.rb +22 -20
  37. data/lib/github_cli/commands/milestones.rb +43 -13
  38. data/lib/github_cli/commands/references.rb +21 -6
  39. data/lib/github_cli/commands/starring.rb +3 -2
  40. data/lib/github_cli/commands/tags.rb +16 -1
  41. data/lib/github_cli/commands/trees.rb +11 -5
  42. data/lib/github_cli/commands/watching.rb +3 -2
  43. data/lib/github_cli/config.rb +15 -6
  44. data/lib/github_cli/dsl.rb +2 -2
  45. data/lib/github_cli/formatter.rb +2 -3
  46. data/lib/github_cli/formatters/csv.rb +29 -14
  47. data/lib/github_cli/formatters/table.rb +2 -3
  48. data/lib/github_cli/man/gcli-config.1 +17 -13
  49. data/lib/github_cli/man/gcli-config.1.txt +23 -21
  50. data/lib/github_cli/vendor/thor/actions/create_link.rb +3 -0
  51. data/lib/github_cli/vendor/thor/actions/directory.rb +29 -10
  52. data/lib/github_cli/vendor/thor/actions/file_manipulation.rb +9 -3
  53. data/lib/github_cli/vendor/thor/actions.rb +18 -18
  54. data/lib/github_cli/vendor/thor/base.rb +97 -89
  55. data/lib/github_cli/vendor/thor/{task.rb → command.rb} +16 -12
  56. data/lib/github_cli/vendor/thor/core_ext/hash_with_indifferent_access.rb +5 -0
  57. data/lib/github_cli/vendor/thor/core_ext/io_binary_read.rb +12 -0
  58. data/lib/github_cli/vendor/thor/error.rb +4 -7
  59. data/lib/github_cli/vendor/thor/group.rb +34 -32
  60. data/lib/github_cli/vendor/thor/invocation.rb +28 -26
  61. data/lib/github_cli/vendor/thor/parser/options.rb +66 -26
  62. data/lib/github_cli/vendor/thor/rake_compat.rb +3 -2
  63. data/lib/github_cli/vendor/thor/runner.rb +21 -20
  64. data/lib/github_cli/vendor/thor/shell/basic.rb +20 -16
  65. data/lib/github_cli/vendor/thor/shell/color.rb +13 -9
  66. data/lib/github_cli/vendor/thor/shell/html.rb +13 -9
  67. data/lib/github_cli/vendor/thor/util.rb +214 -210
  68. data/lib/github_cli/vendor/thor/version.rb +1 -1
  69. data/lib/github_cli/vendor/thor.rb +232 -153
  70. data/lib/github_cli/version.rb +1 -1
  71. data/man/gcli-config.1.ronn +14 -11
  72. data/spec/github_cli/commands/assignees_spec.rb +20 -0
  73. data/spec/github_cli/commands/blobs_spec.rb +21 -0
  74. data/spec/github_cli/commands/collaborators_spec.rb +31 -0
  75. data/spec/github_cli/commands/commits_spec.rb +26 -0
  76. data/spec/github_cli/commands/emails_spec.rb +24 -0
  77. data/spec/github_cli/commands/events_spec.rb +56 -0
  78. data/spec/github_cli/commands/followers_spec.rb +44 -0
  79. data/spec/github_cli/commands/keys_spec.rb +36 -0
  80. data/spec/github_cli/commands/labels_spec.rb +61 -0
  81. data/spec/github_cli/commands/milestones_spec.rb +47 -0
  82. data/spec/github_cli/commands/references_spec.rb +42 -0
  83. data/spec/github_cli/commands/starring_spec.rb +40 -0
  84. data/spec/github_cli/commands/tags_spec.rb +26 -0
  85. data/spec/github_cli/commands/trees_spec.rb +32 -0
  86. data/spec/github_cli/commands/watching_spec.rb +40 -0
  87. data/spec/github_cli/config_spec.rb +109 -116
  88. data/spec/github_cli/util/convert_value_spec.rb +19 -0
  89. data/spec/github_cli/util/convert_values_spec.rb +14 -0
  90. data/spec/github_cli/util_spec.rb +0 -29
  91. metadata +51 -19
  92. data/lib/github_cli/vendor/thor/core_ext/dir_escape.rb +0 -0
  93. data/lib/github_cli/vendor/thor/core_ext/file_binary_read.rb +0 -9
  94. data/lib/github_cli/vendor/thor/empty.txt +0 -0
@@ -1,22 +1,24 @@
1
+ require 'set'
1
2
  require 'thor/base'
2
3
 
3
4
  class Thor
4
5
  class << self
5
- # Sets the default task when thor is executed without an explicit task to be called.
6
+ # Sets the default command when thor is executed without an explicit command to be called.
6
7
  #
7
8
  # ==== Parameters
8
- # meth<Symbol>:: name of the default task
9
- #
10
- def default_task(meth=nil)
11
- case meth
12
- when :none
13
- @default_task = 'help'
14
- when nil
15
- @default_task ||= from_superclass(:default_task, 'help')
16
- else
17
- @default_task = meth.to_s
9
+ # meth<Symbol>:: name of the default command
10
+ #
11
+ def default_command(meth=nil)
12
+ @default_command = case meth
13
+ when :none
14
+ 'help'
15
+ when nil
16
+ @default_command || from_superclass(:default_command, 'help')
17
+ else
18
+ meth.to_s
18
19
  end
19
20
  end
21
+ alias default_task default_command
20
22
 
21
23
  # Registers another Thor subclass as a command.
22
24
  #
@@ -35,7 +37,7 @@ class Thor
35
37
  end
36
38
  end
37
39
 
38
- # Defines the usage and the description of the next task.
40
+ # Defines the usage and the description of the next command.
39
41
  #
40
42
  # ==== Parameters
41
43
  # usage<String>
@@ -44,29 +46,29 @@ class Thor
44
46
  #
45
47
  def desc(usage, description, options={})
46
48
  if options[:for]
47
- task = find_and_refresh_task(options[:for])
48
- task.usage = usage if usage
49
- task.description = description if description
49
+ command = find_and_refresh_command(options[:for])
50
+ command.usage = usage if usage
51
+ command.description = description if description
50
52
  else
51
53
  @usage, @desc, @hide = usage, description, options[:hide] || false
52
54
  end
53
55
  end
54
56
 
55
- # Defines the long description of the next task.
57
+ # Defines the long description of the next command.
56
58
  #
57
59
  # ==== Parameters
58
60
  # long description<String>
59
61
  #
60
62
  def long_desc(long_description, options={})
61
63
  if options[:for]
62
- task = find_and_refresh_task(options[:for])
63
- task.long_description = long_description if long_description
64
+ command = find_and_refresh_command(options[:for])
65
+ command.long_description = long_description if long_description
64
66
  else
65
67
  @long_desc = long_description
66
68
  end
67
69
  end
68
70
 
69
- # Maps an input to a task. If you define:
71
+ # Maps an input to a command. If you define:
70
72
  #
71
73
  # map "-T" => "list"
72
74
  #
@@ -74,10 +76,10 @@ class Thor
74
76
  #
75
77
  # thor -T
76
78
  #
77
- # Will invoke the list task.
79
+ # Will invoke the list command.
78
80
  #
79
81
  # ==== Parameters
80
- # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given task.
82
+ # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given command.
81
83
  #
82
84
  def map(mappings=nil)
83
85
  @map ||= from_superclass(:map, {})
@@ -95,7 +97,7 @@ class Thor
95
97
  @map
96
98
  end
97
99
 
98
- # Declares the options for the next task to be declared.
100
+ # Declares the options for the next command to be declared.
99
101
  #
100
102
  # ==== Parameters
101
103
  # Hash[Symbol => Object]:: The hash key is the name of the option and the value
@@ -111,15 +113,15 @@ class Thor
111
113
  alias options method_options
112
114
 
113
115
  # Adds an option to the set of method options. If :for is given as option,
114
- # it allows you to change the options from a previous defined task.
116
+ # it allows you to change the options from a previous defined command.
115
117
  #
116
- # def previous_task
118
+ # def previous_command
117
119
  # # magic
118
120
  # end
119
121
  #
120
- # method_option :foo => :bar, :for => :previous_task
122
+ # method_option :foo => :bar, :for => :previous_command
121
123
  #
122
- # def next_task
124
+ # def next_command
123
125
  # # magic
124
126
  # end
125
127
  #
@@ -138,38 +140,38 @@ class Thor
138
140
  #
139
141
  def method_option(name, options={})
140
142
  scope = if options[:for]
141
- find_and_refresh_task(options[:for]).options
143
+ find_and_refresh_command(options[:for]).options
142
144
  else
143
145
  method_options
144
146
  end
145
147
 
146
148
  build_option(name, options, scope)
147
149
  end
148
-
149
150
  alias option method_option
150
151
 
151
- # Prints help information for the given task.
152
+ # Prints help information for the given command.
152
153
  #
153
154
  # ==== Parameters
154
155
  # shell<Thor::Shell>
155
- # task_name<String>
156
+ # command_name<String>
156
157
  #
157
- def task_help(shell, task_name)
158
- meth = normalize_task_name(task_name)
159
- task = all_tasks[meth]
160
- handle_no_task_error(meth) unless task
158
+ def command_help(shell, command_name)
159
+ meth = normalize_command_name(command_name)
160
+ command = all_commands[meth]
161
+ handle_no_command_error(meth) unless command
161
162
 
162
163
  shell.say "Usage:"
163
- shell.say " #{banner(task)}"
164
+ shell.say " #{banner(command)}"
164
165
  shell.say
165
- class_options_help(shell, nil => task.options.map { |_, o| o })
166
- if task.long_description
166
+ class_options_help(shell, nil => command.options.map { |_, o| o })
167
+ if command.long_description
167
168
  shell.say "Description:"
168
- shell.print_wrapped(task.long_description, :indent => 2)
169
+ shell.print_wrapped(command.long_description, :indent => 2)
169
170
  else
170
- shell.say task.description
171
+ shell.say command.description
171
172
  end
172
173
  end
174
+ alias task_help command_help
173
175
 
174
176
  # Prints help information for this class.
175
177
  #
@@ -177,32 +179,34 @@ class Thor
177
179
  # shell<Thor::Shell>
178
180
  #
179
181
  def help(shell, subcommand = false)
180
- list = printable_tasks(true, subcommand)
182
+ list = printable_commands(true, subcommand)
181
183
  Thor::Util.thor_classes_in(self).each do |klass|
182
- list += klass.printable_tasks(false)
184
+ list += klass.printable_commands(false)
183
185
  end
184
186
  list.sort!{ |a,b| a[0] <=> b[0] }
185
187
 
186
- shell.say "Tasks:"
188
+ shell.say "Commands:"
187
189
  shell.print_table(list, :indent => 2, :truncate => true)
188
190
  shell.say
189
191
  class_options_help(shell)
190
192
  end
191
193
 
192
- # Returns tasks ready to be printed.
193
- def printable_tasks(all = true, subcommand = false)
194
- (all ? all_tasks : tasks).map do |_, task|
195
- next if task.hidden?
194
+ # Returns commands ready to be printed.
195
+ def printable_commands(all = true, subcommand = false)
196
+ (all ? all_commands : commands).map do |_, command|
197
+ next if command.hidden?
196
198
  item = []
197
- item << banner(task, false, subcommand)
198
- item << (task.description ? "# #{task.description.gsub(/\s+/m,' ')}" : "")
199
+ item << banner(command, false, subcommand)
200
+ item << (command.description ? "# #{command.description.gsub(/\s+/m,' ')}" : "")
199
201
  item
200
202
  end.compact
201
203
  end
204
+ alias printable_tasks printable_commands
202
205
 
203
206
  def subcommands
204
207
  @subcommands ||= from_superclass(:subcommands, [])
205
208
  end
209
+ alias subtasks subcommands
206
210
 
207
211
  def subcommand(subcommand, subcommand_class)
208
212
  self.subcommands << subcommand.to_s
@@ -210,9 +214,10 @@ class Thor
210
214
 
211
215
  define_method(subcommand) do |*args|
212
216
  args, opts = Thor::Arguments.split(args)
213
- invoke subcommand_class, args, opts
217
+ invoke subcommand_class, args, opts, :invoked_via_subcommand => true, :class_options => options
214
218
  end
215
219
  end
220
+ alias subtask subcommand
216
221
 
217
222
  # Extend check unknown options to accept a hash of conditions.
218
223
  #
@@ -235,10 +240,10 @@ class Thor
235
240
  options = check_unknown_options
236
241
  return false unless options
237
242
 
238
- task = config[:current_task]
239
- return true unless task
243
+ command = config[:current_command]
244
+ return true unless command
240
245
 
241
- name = task.name
246
+ name = command.name
242
247
 
243
248
  if subcommands.include?(name)
244
249
  false
@@ -251,129 +256,203 @@ class Thor
251
256
  end
252
257
  end
253
258
 
254
- protected
255
-
256
- # The method responsible for dispatching given the args.
257
- def dispatch(meth, given_args, given_opts, config) #:nodoc:
258
- meth ||= retrieve_task_name(given_args)
259
- task = all_tasks[normalize_task_name(meth)]
260
-
261
- if task
262
- args, opts = Thor::Options.split(given_args)
263
- else
264
- args, opts = given_args, nil
265
- task = Thor::DynamicTask.new(meth)
266
- end
259
+ # Stop parsing of options as soon as an unknown option or a regular
260
+ # argument is encountered. All remaining arguments are passed to the command.
261
+ # This is useful if you have a command that can receive arbitrary additional
262
+ # options, and where those additional options should not be handled by
263
+ # Thor.
264
+ #
265
+ # ==== Example
266
+ #
267
+ # To better understand how this is useful, let's consider a command that calls
268
+ # an external command. A user may want to pass arbitrary options and
269
+ # arguments to that command. The command itself also accepts some options,
270
+ # which should be handled by Thor.
271
+ #
272
+ # class_option "verbose", :type => :boolean
273
+ # stop_on_unknown_option! :exec
274
+ # check_unknown_options! :except => :exec
275
+ #
276
+ # desc "exec", "Run a shell command"
277
+ # def exec(*args)
278
+ # puts "diagnostic output" if options[:verbose]
279
+ # Kernel.exec(*args)
280
+ # end
281
+ #
282
+ # Here +exec+ can be called with +--verbose+ to get diagnostic output,
283
+ # e.g.:
284
+ #
285
+ # $ thor exec --verbose echo foo
286
+ # diagnostic output
287
+ # foo
288
+ #
289
+ # But if +--verbose+ is given after +echo+, it is passed to +echo+ instead:
290
+ #
291
+ # $ thor exec echo --verbose foo
292
+ # --verbose foo
293
+ #
294
+ # ==== Parameters
295
+ # Symbol ...:: A list of commands that should be affected.
296
+ def stop_on_unknown_option!(*command_names)
297
+ @stop_on_unknown_option ||= Set.new
298
+ @stop_on_unknown_option.merge(command_names)
299
+ end
267
300
 
268
- opts = given_opts || opts || []
269
- config.merge!(:current_task => task, :task_options => task.options)
301
+ def stop_on_unknown_option?(command) #:nodoc:
302
+ !!@stop_on_unknown_option && @stop_on_unknown_option.include?(command.name.to_sym)
303
+ end
270
304
 
271
- instance = new(args, opts, config)
272
- yield instance if block_given?
273
- args = instance.args
274
- trailing = args[Range.new(arguments.size, -1)]
275
- instance.invoke_task(task, trailing || [])
305
+ protected
306
+
307
+ # The method responsible for dispatching given the args.
308
+ def dispatch(meth, given_args, given_opts, config) #:nodoc:
309
+ # There is an edge case when dispatching from a subcommand.
310
+ # A problem occurs invoking the default command. This case occurs
311
+ # when arguments are passed and a default command is defined, and
312
+ # the first given_args does not match the default command.
313
+ # Thor use "help" by default so we skip that case.
314
+ # Note the call to retrieve_command_name. It's called with
315
+ # given_args.dup since that method calls args.shift. Then lookup
316
+ # the command normally. If the first item in given_args is not
317
+ # a command then use the default command. The given_args will be
318
+ # intact later since dup was used.
319
+ if config[:invoked_via_subcommand] && given_args.size >= 1 && default_command != "help" && given_args.first != default_command
320
+ meth ||= retrieve_command_name(given_args.dup)
321
+ command = all_commands[normalize_command_name(meth)]
322
+ command ||= all_commands[normalize_command_name(default_command)]
323
+ else
324
+ meth ||= retrieve_command_name(given_args)
325
+ command = all_commands[normalize_command_name(meth)]
276
326
  end
277
327
 
278
- # The banner for this class. You can customize it if you are invoking the
279
- # thor class by another ways which is not the Thor::Runner. It receives
280
- # the task that is going to be invoked and a boolean which indicates if
281
- # the namespace should be displayed as arguments.
282
- #
283
- def banner(task, namespace = nil, subcommand = false)
284
- "#{basename} #{task.formatted_usage(self, $thor_runner, subcommand)}"
328
+ if command
329
+ args, opts = Thor::Options.split(given_args)
330
+ if stop_on_unknown_option?(command) && !args.empty?
331
+ # given_args starts with a non-option, so we treat everything as
332
+ # ordinary arguments
333
+ args.concat opts
334
+ opts.clear
335
+ end
336
+ else
337
+ args, opts = given_args, nil
338
+ command = Thor::DynamicCommand.new(meth)
285
339
  end
286
340
 
287
- def baseclass #:nodoc:
288
- Thor
289
- end
341
+ opts = given_opts || opts || []
342
+ config.merge!(:current_command => command, :command_options => command.options)
290
343
 
291
- def create_task(meth) #:nodoc:
292
- if @usage && @desc
293
- base_class = @hide ? Thor::HiddenTask : Thor::Task
294
- tasks[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
295
- @usage, @desc, @long_desc, @method_options, @hide = nil
296
- true
297
- elsif self.all_tasks[meth] || meth == "method_missing"
298
- true
299
- else
300
- puts "[WARNING] Attempted to create task #{meth.inspect} without usage or description. " <<
301
- "Call desc if you want this method to be available as task or declare it inside a " <<
302
- "no_tasks{} block. Invoked from #{caller[1].inspect}."
303
- false
304
- end
305
- end
344
+ instance = new(args, opts, config)
345
+ yield instance if block_given?
346
+ args = instance.args
347
+ trailing = args[Range.new(arguments.size, -1)]
348
+ instance.invoke_command(command, trailing || [])
349
+ end
306
350
 
307
- def initialize_added #:nodoc:
308
- class_options.merge!(method_options)
309
- @method_options = nil
310
- end
351
+ # The banner for this class. You can customize it if you are invoking the
352
+ # thor class by another ways which is not the Thor::Runner. It receives
353
+ # the command that is going to be invoked and a boolean which indicates if
354
+ # the namespace should be displayed as arguments.
355
+ #
356
+ def banner(command, namespace = nil, subcommand = false)
357
+ "#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}"
358
+ end
311
359
 
312
- # Retrieve the task name from given args.
313
- def retrieve_task_name(args) #:nodoc:
314
- meth = args.first.to_s unless args.empty?
315
- if meth && (map[meth] || meth !~ /^\-/)
316
- args.shift
317
- else
318
- nil
319
- end
360
+ def baseclass #:nodoc:
361
+ Thor
362
+ end
363
+
364
+ def create_command(meth) #:nodoc:
365
+ if @usage && @desc
366
+ base_class = @hide ? Thor::HiddenCommand : Thor::Command
367
+ commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
368
+ @usage, @desc, @long_desc, @method_options, @hide = nil
369
+ true
370
+ elsif self.all_commands[meth] || meth == "method_missing"
371
+ true
372
+ else
373
+ puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " <<
374
+ "Call desc if you want this method to be available as command or declare it inside a " <<
375
+ "no_commands{} block. Invoked from #{caller[1].inspect}."
376
+ false
320
377
  end
378
+ end
379
+ alias create_task create_command
321
380
 
322
- # receives a (possibly nil) task name and returns a name that is in
323
- # the tasks hash. In addition to normalizing aliases, this logic
324
- # will determine if a shortened command is an unambiguous substring of
325
- # a task or alias.
326
- #
327
- # +normalize_task_name+ also converts names like +animal-prison+
328
- # into +animal_prison+.
329
- def normalize_task_name(meth) #:nodoc:
330
- return default_task.to_s.gsub('-', '_') unless meth
331
-
332
- possibilities = find_task_possibilities(meth)
333
- if possibilities.size > 1
334
- raise ArgumentError, "Ambiguous task #{meth} matches [#{possibilities.join(', ')}]"
335
- elsif possibilities.size < 1
336
- meth = meth || default_task
337
- elsif map[meth]
338
- meth = map[meth]
339
- else
340
- meth = possibilities.first
341
- end
381
+ def initialize_added #:nodoc:
382
+ class_options.merge!(method_options)
383
+ @method_options = nil
384
+ end
342
385
 
343
- meth.to_s.gsub('-','_') # treat foo-bar as foo_bar
386
+ # Retrieve the command name from given args.
387
+ def retrieve_command_name(args) #:nodoc:
388
+ meth = args.first.to_s unless args.empty?
389
+ if meth && (map[meth] || meth !~ /^\-/)
390
+ args.shift
391
+ else
392
+ nil
344
393
  end
394
+ end
395
+ alias retrieve_task_name retrieve_command_name
345
396
 
346
- # this is the logic that takes the task name passed in by the user
347
- # and determines whether it is an unambiguous substrings of a task or
348
- # alias name.
349
- def find_task_possibilities(meth)
350
- len = meth.to_s.length
351
- possibilities = all_tasks.merge(map).keys.select { |n| meth == n[0, len] }.sort
352
- unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
353
-
354
- if possibilities.include?(meth)
355
- [meth]
356
- elsif unique_possibilities.size == 1
357
- unique_possibilities
358
- else
359
- possibilities
360
- end
397
+ # receives a (possibly nil) command name and returns a name that is in
398
+ # the commands hash. In addition to normalizing aliases, this logic
399
+ # will determine if a shortened command is an unambiguous substring of
400
+ # a command or alias.
401
+ #
402
+ # +normalize_command_name+ also converts names like +animal-prison+
403
+ # into +animal_prison+.
404
+ def normalize_command_name(meth) #:nodoc:
405
+ return default_command.to_s.gsub('-', '_') unless meth
406
+
407
+ possibilities = find_command_possibilities(meth)
408
+ if possibilities.size > 1
409
+ raise ArgumentError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]"
410
+ elsif possibilities.size < 1
411
+ meth = meth || default_command
412
+ elsif map[meth]
413
+ meth = map[meth]
414
+ else
415
+ meth = possibilities.first
361
416
  end
362
417
 
363
- def subcommand_help(cmd)
364
- desc "help [COMMAND]", "Describe subcommands or one specific subcommand"
365
- class_eval <<-RUBY
366
- def help(task = nil, subcommand = true); super; end
367
- RUBY
418
+ meth.to_s.gsub('-','_') # treat foo-bar as foo_bar
419
+ end
420
+ alias normalize_task_name normalize_command_name
421
+
422
+ # this is the logic that takes the command name passed in by the user
423
+ # and determines whether it is an unambiguous substrings of a command or
424
+ # alias name.
425
+ def find_command_possibilities(meth)
426
+ len = meth.to_s.length
427
+ possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort
428
+ unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
429
+
430
+ if possibilities.include?(meth)
431
+ [meth]
432
+ elsif unique_possibilities.size == 1
433
+ unique_possibilities
434
+ else
435
+ possibilities
368
436
  end
437
+ end
438
+ alias find_task_possibilities find_command_possibilities
439
+
440
+ def subcommand_help(cmd)
441
+ desc "help [COMMAND]", "Describe subcommands or one specific subcommand"
442
+ class_eval <<-RUBY
443
+ def help(command = nil, subcommand = true); super; end
444
+ RUBY
445
+ end
446
+ alias subtask_help subcommand_help
447
+
369
448
  end
370
449
 
371
450
  include Thor::Base
372
451
 
373
452
  map HELP_MAPPINGS => :help
374
453
 
375
- desc "help [TASK]", "Describe available tasks or one specific task"
376
- def help(task = nil, subcommand = false)
377
- task ? self.class.task_help(shell, task) : self.class.help(shell, subcommand)
454
+ desc "help [COMMAND]", "Describe available commands or one specific command"
455
+ def help(command = nil, subcommand = false)
456
+ command ? self.class.command_help(shell, command) : self.class.help(shell, subcommand)
378
457
  end
379
458
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module GithubCLI
4
- VERSION = "0.5.3"
4
+ VERSION = "0.5.4"
5
5
  end
@@ -3,9 +3,9 @@ gcli-config(1) - Get or set global or local configuration options
3
3
 
4
4
  ## SYNOPSIS
5
5
 
6
- `gcli config` --global|--local name [value]<br>
7
- `gcli config` --global|--local `-l | -list` [name_regex]<br>
8
- `gcli config` --global|--local `-e | --edit`
6
+ `gcli config` [--local] name [value]<br>
7
+ `gcli config` [--local] `-l | -list` [name_regex]<br>
8
+ `gcli config` [--local] `-e | --edit`
9
9
 
10
10
  ## DESCRIPTION
11
11
 
@@ -23,9 +23,6 @@ This command line will fail (with the exit code ret) if:
23
23
 
24
24
  ## OPTIONS
25
25
 
26
- * `--global`:
27
- Writes configuration settings to global ~/.githubrc file inside user home directory.
28
-
29
26
  * `--local`:
30
27
  Writes cofinguration settings inside the current directory to the .githubrc file.
31
28
 
@@ -47,11 +44,17 @@ The configuration file is written in `yaml`. Therfore all formatting rules are d
47
44
 
48
45
  ### VARIABLES
49
46
 
50
- * `auth.token`:
47
+ * `user.token`:
51
48
  Authentication token.
52
49
 
53
- * `auth.basic`:
54
- Basic credentials in the form `login:password`.
50
+ * `user.login`:
51
+ Basic login credentials.
52
+
53
+ * `user.password`:
54
+ Basic password credentials.
55
+
56
+ * `core.adapter`:
57
+ Sets http adapter used to perform requests to GitHub API v3.
55
58
 
56
59
  * `core.endpoint`:
57
60
  Sets host path used as the base for all requests to GitHub API v3.
@@ -63,7 +66,7 @@ The configuration file is written in `yaml`. Therfore all formatting rules are d
63
66
  The command that will be used to paginate output. Can be overridden with PAGER environment variable. less
64
67
 
65
68
  * `core.no-pager`:
66
- false
69
+ Switched off results paging.
67
70
 
68
71
  * `core.no-color`:
69
72
  If set to true disables color output. By default is set to false.
@@ -71,7 +74,7 @@ The configuration file is written in `yaml`. Therfore all formatting rules are d
71
74
  * `core.format`:
72
75
  Determines output formatting. Defaults to table output.
73
76
 
74
- * `core.auto`:
77
+ * `core.auto_pagination`:
75
78
  Automatic pagination of requests to GitHub.
76
79
 
77
80
  * `core.aliases`:
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe GithubCLI::Commands::Assignees do
6
+ let(:format) { 'table' }
7
+ let(:user) { 'peter-murach' }
8
+ let(:repo) { 'github_cli' }
9
+ let(:api_class) { GithubCLI::Assignee }
10
+
11
+ it "invokes assignee:list" do
12
+ api_class.should_receive(:all).with(user, repo, {}, format)
13
+ subject.invoke "assignee:list", [user, repo]
14
+ end
15
+
16
+ it "invokes assignee:check" do
17
+ api_class.should_receive(:check).with(user, repo, 'git', {}, format)
18
+ subject.invoke "assignee:check", [user, repo, 'git']
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe GithubCLI::Commands::Blobs do
6
+ let(:format) { 'table' }
7
+ let(:user) { 'peter-murach' }
8
+ let(:repo) { 'github_cli' }
9
+ let(:sha) { '3a0f86fb8db8eea7ccbb9a95f325ddbedfb25e15' }
10
+ let(:api_class) { GithubCLI::Blob }
11
+
12
+ it "invokes blob:get" do
13
+ api_class.should_receive(:get).with(user, repo, sha, {}, format)
14
+ subject.invoke "blob:get", [user, repo, sha]
15
+ end
16
+
17
+ it "invokes blob:create" do
18
+ api_class.should_receive(:create).with(user, repo, {}, format)
19
+ subject.invoke "blob:create", [user, repo]
20
+ end
21
+ end