gli 2.18.0 → 2.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37750b02cb524b2401b75d1f53722be230486faac88638a06c2722e8aba595bb
4
- data.tar.gz: 73964afbb6c60b87be8a7cdd688cc9b54a3624b20ea32cddd1ae3ac5ba75da63
3
+ metadata.gz: 7089f9a6b96c1d569c7f41a03d8ffce30f3f9498ea39ca7c6c7b3717d96f71ec
4
+ data.tar.gz: '03592a617ed24d6595d0b5c505c2f7dea8ebcc000d654011a0e65e795838564a'
5
5
  SHA512:
6
- metadata.gz: f822477176088b91c87fb1a9902e5e856c32c9904c2e8773d38566ab821f7f612ef18bcfc5a9dd67ae8c8461a6afaed60fa57fe939b0d965f707a4da88980eee
7
- data.tar.gz: a68d246f06f74ef758fe75e79f9a7e6cf8a9d8667d71a1dfc2702aa1ce7f5b925a8f433b27ea3171fb1453d5b7a84d8983bb27a93df4c31a10c863f89de39b41
6
+ metadata.gz: 7d1611797b8f4aa7ef04671912a193fbf9882fbfd1bd0106f5d403c8da126cb24ae98fd9accaf8d72e4127d97edb13a79679c5589f0136152a945fe2e1976c08
7
+ data.tar.gz: 41dd9b803e0e660b0ba7f4b6f33ed591da957c99ac52a09e0fe3e171df668175ac77c9513deda9138602ad620c19f1f4470f1aa234e9ec0c84bae1cff8aa3e6a
@@ -0,0 +1 @@
1
+ ruby 2.7.1
@@ -1,10 +1,6 @@
1
- = Git-Like Interface Command Line Parser
1
+ = GLI, the Git-Like Interface Command Line Parser
2
2
 
3
- GLI is the best way to make a "command-suite" command-line application, e.g. one like <tt>git</tt> (for the best way to make a
4
- simpler command-line application, check out methadone[http://www.github.com/davetron5000/methadone]).
5
-
6
- GLI allows you to make a polished, easy-to-maintain command-line application without a lot
7
- of syntax, but without restricting you in any way from the power of +OptionParser+.
3
+ GLI allows you to create command-line app in Ruby that behaves like <tt>git</tt> in that it takes subcommands to perform a series of complex action, e.g. <tt>git remote add</tt>.
8
4
 
9
5
  * {Overview}[http://davetron5000.github.com/gli]
10
6
  * {Source on Github}[http://github.com/davetron5000/gli]
@@ -12,16 +8,40 @@ of syntax, but without restricting you in any way from the power of +OptionParse
12
8
 
13
9
  {<img src="https://secure.travis-ci.org/davetron5000/gli.svg?branch=gli-2" alt="Build Status" />}[https://travis-ci.org/davetron5000/gli]
14
10
 
11
+ == What Problem does GLI Solve?
12
+
13
+ Creating a command-line app that uses subcommands, each of which might accept different command-line options, is somewhat difficult with Ruby's built-in <tt>OptionParser</tt>. GLI provides an API that wraps <tt>OptionParser</tt> so that you can create a subcommand-based command-line app with minimal boilerplate. This API also produces complete documentation for your command-line app.
14
+
15
+ == Why is GLI's solution different from others?
16
+
17
+ There are other RubyGems that allow you to create a command-line app that takes subcommands. These solutions are often quite limited (e.g. they don't allow deeply nested subcommand structures or sophisticated command-line options per subcommand), or require more code that we think is needed. Some solutions make it difficult or impossible to properly document your command-line app.
18
+
19
+ == What you need to know to use GLI
20
+
21
+ You should know Ruby, and have a basic understanding of how the UNIX command line works: standard input, standard output, standard error, and exit codes.
22
+
15
23
  == Use
16
24
 
17
25
  Install if you need to:
18
26
 
19
27
  gem install gli
20
28
 
29
+ You can validate you have installed it correctly by running <tt>gli help</tt>. You should see formatted help output.
30
+
31
+ If you are using GLI in another application, add it to your <tt>Gemfile</tt>:
32
+
33
+ gem "gli"
34
+
35
+ You can test your install via Bundler by running <tt>bundle exec gli help</tt>. This should produce formatted help output from GLI.
36
+
37
+ == Getting Started
38
+
21
39
  The simplest way to get started is to create a scaffold project
22
40
 
23
41
  gli init todo list add complete
24
42
 
43
+ (note if you installed via Bundler you will need to execute <tt>bundle exec gli init todo list add complete</tt>)
44
+
25
45
  This will create a basic scaffold project in <tt>./todo</tt> with:
26
46
 
27
47
  * executable in <tt>./todo/bin/todo</tt>. This file demonstrates most of what you need to describe your command line interface.
data/bin/gli CHANGED
@@ -36,7 +36,7 @@ long_desc <
36
36
  EOS
37
37
  arg :project_name
38
38
  arg :command_name, [:optional, :multiple]
39
- arg_name "project_name [command_name][, [command_name]]*"
39
+ arg_name "project_name [command_name]..."
40
40
  command [:init,:scaffold] do |c|
41
41
 
42
42
  c.switch :e,:ext, :desc => 'Create an ext dir'
@@ -49,7 +49,7 @@ Feature: The GLI executable works as intended
49
49
  init - Create a new GLI-based project
50
50
 
51
51
  SYNOPSIS
52
- gli [global options] init [command options] project_name [command_name][, [command_name]]*
52
+ gli [global options] init [command options] project_name [command_name]...
53
53
 
54
54
  DESCRIPTION
55
55
  This will create a scaffold command line project that uses GLI for command
@@ -8,6 +8,7 @@ Feature: The scaffold GLI generates works
8
8
  And GLI's libs are in my path
9
9
  And my terminal size is "80x24"
10
10
 
11
+ @slow-command
11
12
  Scenario: Scaffold generates and things look good
12
13
  When I run `gli init --rvmrc todo add complete list`
13
14
  Then the exit status should be 0
@@ -35,6 +36,7 @@ Feature: The scaffold GLI generates works
35
36
  |todo/bin |
36
37
  |todo/test |
37
38
  |todo/lib |
39
+ |todo/.git |
38
40
  And the following files should exist:
39
41
  |todo/bin/todo |
40
42
  |todo/README.rdoc |
@@ -0,0 +1,5 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Before '@slow-command' do
4
+ @aruba_timeout_seconds = 10
5
+ end
@@ -191,7 +191,7 @@ Feature: The todo app has a nice user interface
191
191
  list - List things, such as tasks or contexts
192
192
 
193
193
  SYNOPSIS
194
- todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]*
194
+ todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task]...
195
195
  todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar]
196
196
 
197
197
  DESCRIPTION
@@ -261,7 +261,7 @@ Feature: The todo app has a nice user interface
261
261
  list - List things, such as tasks or contexts
262
262
 
263
263
  SYNOPSIS
264
- todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]*
264
+ todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task]...
265
265
  todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar]
266
266
 
267
267
  DESCRIPTION
@@ -286,7 +286,7 @@ Feature: The todo app has a nice user interface
286
286
  list - List things, such as tasks or contexts
287
287
 
288
288
  SYNOPSIS
289
- todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]*
289
+ todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task]...
290
290
  todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar]
291
291
 
292
292
  DESCRIPTION
@@ -319,7 +319,7 @@ Feature: The todo app has a nice user interface
319
319
  list - List things, such as tasks or contexts
320
320
 
321
321
  SYNOPSIS
322
- todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]*
322
+ todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task]...
323
323
  todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar]
324
324
 
325
325
  DESCRIPTION
@@ -343,7 +343,7 @@ Feature: The todo app has a nice user interface
343
343
  tasks - List tasks
344
344
 
345
345
  SYNOPSIS
346
- todo [global options] list tasks [command options] [task][, [task]]*
346
+ todo [global options] list tasks [command options] [task]...
347
347
  todo [global options] list tasks [command options] open [--flag arg] [-x arg]
348
348
 
349
349
  DESCRIPTION
@@ -370,9 +370,9 @@ Feature: The todo app has a nice user interface
370
370
  todo [global options] create
371
371
  todo [global options] create contexts [context_name]
372
372
  todo [global options] create relation_1-1 first second [name]
373
- todo [global options] create relation_1-n first second[, second]* [name]
374
- todo [global options] create relation_n-1 first[, first]* second [name]
375
- todo [global options] create tasks task_name[, task_name]*
373
+ todo [global options] create relation_1-n first second... [name]
374
+ todo [global options] create relation_n-1 first... second [name]
375
+ todo [global options] create tasks task_name...
376
376
 
377
377
  COMMANDS
378
378
  <default> - Makes a new task
@@ -530,7 +530,7 @@ Feature: The todo app has a nice user interface
530
530
  list - List things, such as tasks or contexts
531
531
 
532
532
  SYNOPSIS
533
- todo [global options] list [command options] [tasks] [subcommand options] [task][, [task]]*
533
+ todo [global options] list [command options] [tasks] [subcommand options] [task]...
534
534
  todo [global options] list [command options] contexts [subcommand options]
535
535
 
536
536
  DESCRIPTION
@@ -92,7 +92,7 @@ Feature: The todo app is backwards compatible with legacy subcommand parsing
92
92
  SYNOPSIS
93
93
  todo [global options] create
94
94
  todo [global options] create contexts [context_name]
95
- todo [global options] create tasks task_name[, task_name]*
95
+ todo [global options] create tasks task_name...
96
96
 
97
97
  COMMANDS
98
98
  <default> - Makes a new task
@@ -20,7 +20,6 @@ spec = Gem::Specification.new do |s|
20
20
  s.extra_rdoc_files = ['README.rdoc', 'gli.rdoc']
21
21
  s.rdoc_options << '--title' << 'Git Like Interface' << '--main' << 'README.rdoc'
22
22
  s.bindir = 'bin'
23
- s.rubyforge_project = 'gli'
24
23
  s.add_development_dependency('rake', '~> 0.9.2.2')
25
24
  s.add_development_dependency('rdoc', '~> 4.2')
26
25
  s.add_development_dependency('rainbow', '~> 1.1', '~> 1.1.1')
@@ -166,12 +166,8 @@ module GLI
166
166
 
167
167
  def generate_error_action(arguments)
168
168
  lambda { |global_options,options,arguments|
169
- if am_subcommand?
170
- if arguments.size > 0
171
- raise UnknownCommand,"Unknown command '#{arguments[0]}'"
172
- else
173
- raise BadCommandLine,"Command '#{name}' requires a subcommand"
174
- end
169
+ if am_subcommand? && arguments.size > 0
170
+ raise UnknownCommand,"Unknown command '#{arguments[0]}'"
175
171
  elsif have_subcommands?
176
172
  raise BadCommandLine,"Command '#{name}' requires a subcommand #{self.commands.keys.join(',')}"
177
173
  else
@@ -22,7 +22,7 @@ module GLI
22
22
  arg_desc = "[#{arg_desc}]"
23
23
  end
24
24
  if arg.multiple?
25
- arg_desc = "#{arg_desc}[, #{arg_desc}]*"
25
+ arg_desc = "#{arg_desc}..."
26
26
  end
27
27
  desc = desc + " " + arg_desc
28
28
  end
@@ -37,7 +37,7 @@ module GLI
37
37
  desc = "[#{desc}]"
38
38
  end
39
39
  if arguments_options.include? :multiple
40
- desc = "#{desc}[, #{desc}]*"
40
+ desc = "#{desc}..."
41
41
  end
42
42
  " " + desc
43
43
  end
@@ -31,6 +31,7 @@ module GLI
31
31
  end
32
32
  puts "Created #{rvmrc}"
33
33
  end
34
+ init_git(root_dir, project_name)
34
35
  end
35
36
  end
36
37
 
@@ -369,6 +370,14 @@ EOS
369
370
  true
370
371
  end
371
372
 
373
+ def self.init_git(root_dir, project_name)
374
+ project_dir = "#{root_dir}/#{project_name}"
375
+
376
+ unless system("git", "init", "--quiet", project_dir)
377
+ puts "There was a problem initializing Git. Your gemspec may not work until you have done a successful `git init`"
378
+ end
379
+ end
380
+
372
381
  def self.mkdirs(dirs,force,dry_run)
373
382
  exists = false
374
383
  if !force
@@ -50,7 +50,7 @@ module GLI
50
50
  # command :pack do ...
51
51
  #
52
52
  # Produces the synopsis:
53
- # app.rb [global options] pack output input[, input]*
53
+ # app.rb [global options] pack output input...
54
54
  def arg(name, options=[])
55
55
  @next_arguments ||= []
56
56
  @next_arguments << Argument.new(name, Array(options).flatten)
@@ -29,7 +29,7 @@ module GLI
29
29
  OptionParsingResult.new.tap { |parsing_result|
30
30
  parsing_result.arguments = args
31
31
  parsing_result = @global_option_parser.parse!(parsing_result)
32
- option_parser_class.new(@accepts).parse!(parsing_result, options[:argument_handling_strategy])
32
+ option_parser_class.new(@accepts).parse!(parsing_result, options[:argument_handling_strategy], options[:autocomplete])
33
33
  }
34
34
  end
35
35
 
@@ -117,7 +117,7 @@ module GLI
117
117
  }
118
118
  end
119
119
 
120
- def parse!(parsing_result,argument_handling_strategy)
120
+ def parse!(parsing_result,argument_handling_strategy,autocomplete)
121
121
  parsed_command_options = {}
122
122
  command = parsing_result.command
123
123
  arguments = nil
@@ -131,7 +131,7 @@ module GLI
131
131
  arguments = option_block_parser.parse!(arguments)
132
132
 
133
133
  parsed_command_options[command] = option_parser_factory.options_hash_with_defaults_set!
134
- command_finder = CommandFinder.new(command.commands, :default_command => command.get_default_command)
134
+ command_finder = CommandFinder.new(command.commands, :default_command => command.get_default_command, :autocomplete => autocomplete)
135
135
  next_command_name = arguments.shift
136
136
 
137
137
  verify_required_options!(command.flags, command, parsed_command_options[command])
@@ -178,7 +178,7 @@ module GLI
178
178
  end
179
179
 
180
180
  class LegacyCommandOptionParser < NormalCommandOptionParser
181
- def parse!(parsing_result,argument_handling_strategy)
181
+ def parse!(parsing_result,argument_handling_strategy,autocomplete)
182
182
  command = parsing_result.command
183
183
  option_parser_factory = OptionParserFactory.for_command(command,@accepts)
184
184
  option_block_parser = LegacyCommandOptionBlockParser.new(option_parser_factory, self.error_handler)
@@ -187,7 +187,7 @@ module GLI
187
187
  parsing_result.arguments = option_block_parser.parse!(parsing_result.arguments)
188
188
  parsing_result.command_options = option_parser_factory.options_hash_with_defaults_set!
189
189
 
190
- subcommand,args = find_subcommand(command,parsing_result.arguments)
190
+ subcommand,args = find_subcommand(command,parsing_result.arguments,autocomplete)
191
191
  parsing_result.command = subcommand
192
192
  parsing_result.arguments = args
193
193
  verify_required_options!(command.flags, parsing_result.command, parsing_result.command_options)
@@ -195,7 +195,7 @@ module GLI
195
195
 
196
196
  private
197
197
 
198
- def find_subcommand(command,arguments)
198
+ def find_subcommand(command,arguments,autocomplete)
199
199
  arguments = Array(arguments)
200
200
  command_name = if arguments.empty?
201
201
  nil
@@ -204,15 +204,15 @@ module GLI
204
204
  end
205
205
 
206
206
  default_command = command.get_default_command
207
- finder = CommandFinder.new(command.commands, :default_command => default_command.to_s)
207
+ finder = CommandFinder.new(command.commands, :default_command => default_command.to_s, :autocomplete => autocomplete)
208
208
 
209
209
  begin
210
210
  results = [finder.find_command(command_name),arguments[1..-1]]
211
- find_subcommand(results[0],results[1])
211
+ find_subcommand(results[0],results[1],autocomplete)
212
212
  rescue UnknownCommand, AmbiguousCommand
213
213
  begin
214
214
  results = [finder.find_command(default_command.to_s),arguments]
215
- find_subcommand(results[0],results[1])
215
+ find_subcommand(results[0],results[1],autocomplete)
216
216
  rescue UnknownCommand, AmbiguousCommand
217
217
  [command,arguments]
218
218
  end
@@ -1,5 +1,5 @@
1
1
  module GLI
2
2
  unless const_defined? :VERSION
3
- VERSION = '2.18.0'
3
+ VERSION = '2.19.2'
4
4
  end
5
5
  end
@@ -78,6 +78,31 @@ class TC_testSubCommandParsing < Clean::Test::TestCase
78
78
  }
79
79
  end
80
80
 
81
+ test_that "in loose mode with autocomplete false, it doesn't autocorrect a sub command" do
82
+ Given :app_with_subcommand_storing_results, :normal, false, :loose
83
+ When {
84
+ @app.run(%w(-f global command -f flag -s subcomm -f subflag))
85
+ }
86
+ Then {
87
+ with_clue {
88
+ assert_equal "command",@results[:command_name]
89
+ }
90
+ }
91
+ end
92
+
93
+ test_that "in strict mode with autocomplete false, it doesn't autocorrect a sub command" do
94
+ Given :app_with_subcommand_storing_results, :normal, false, :strict
95
+ When {
96
+ @app.run(%w(-f global command -f flag -s subcomm -f subflag))
97
+ }
98
+ Then {
99
+ with_clue {
100
+ assert_equal nil,@results[:command_name]
101
+ assert @fake_stderr.contained?(/error: Too many arguments for command/)
102
+ }
103
+ }
104
+ end
105
+
81
106
  test_that "in loose mode, argument validation is ignored" do
82
107
  Given :app_with_arguments, 1, 1, false, :loose
83
108
  When :run_app_with_X_arguments, 0
@@ -160,6 +185,41 @@ private
160
185
  raise
161
186
  end
162
187
 
188
+ def app_with_subcommand_storing_results(subcommand_option_handling_strategy, autocomplete, arguments_handling_strategy)
189
+ @app.subcommand_option_handling subcommand_option_handling_strategy
190
+ @app.autocomplete_commands autocomplete
191
+ @app.arguments arguments_handling_strategy
192
+ @app.flag ['f','flag']
193
+ @app.switch ['s','switch']
194
+
195
+ @app.command "command" do |c|
196
+ c.flag ['f','flag']
197
+ c.switch ['s','switch']
198
+ c.action do |global,options,args|
199
+ @results = {
200
+ :command_name => "command",
201
+ :global_options => global,
202
+ :command_options => options,
203
+ :args => args
204
+ }
205
+ end
206
+
207
+ c.command "subcommand" do |subcommand|
208
+ subcommand.flag ['f','flag']
209
+ subcommand.flag ['foo']
210
+ subcommand.switch ['s','switch']
211
+ subcommand.action do |global,options,args|
212
+ @results = {
213
+ :command_name => "subcommand",
214
+ :global_options => global,
215
+ :command_options => options,
216
+ :args => args
217
+ }
218
+ end
219
+ end
220
+ end
221
+ end
222
+
163
223
  def app_with_subcommands_storing_results(subcommand_option_handling_strategy = :legacy)
164
224
  @app.subcommand_option_handling subcommand_option_handling_strategy
165
225
  @app.flag ['f','flag']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gli
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.18.0
4
+ version: 2.19.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Copeland
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-08 00:00:00.000000000 Z
11
+ date: 2020-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -156,6 +156,7 @@ files:
156
156
  - ".gitignore"
157
157
  - ".ruby-gemset"
158
158
  - ".ruby-version"
159
+ - ".tool-versions"
159
160
  - ".travis.yml"
160
161
  - CONTRIBUTING.md
161
162
  - Gemfile
@@ -172,6 +173,7 @@ files:
172
173
  - features/step_definitions/gli_init_steps.rb
173
174
  - features/step_definitions/todo_steps.rb
174
175
  - features/support/env.rb
176
+ - features/support/hooks.rb
175
177
  - features/todo.feature
176
178
  - features/todo_legacy.feature
177
179
  - gli.cheat
@@ -264,7 +266,7 @@ homepage: http://davetron5000.github.com/gli
264
266
  licenses:
265
267
  - Apache-2.0
266
268
  metadata: {}
267
- post_install_message:
269
+ post_install_message:
268
270
  rdoc_options:
269
271
  - "--title"
270
272
  - Git Like Interface
@@ -283,9 +285,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
283
285
  - !ruby/object:Gem::Version
284
286
  version: '0'
285
287
  requirements: []
286
- rubyforge_project: gli
287
- rubygems_version: 2.7.6
288
- signing_key:
288
+ rubygems_version: 3.1.2
289
+ signing_key:
289
290
  specification_version: 4
290
291
  summary: Build command-suite CLI apps that are awesome.
291
292
  test_files:
@@ -295,6 +296,7 @@ test_files:
295
296
  - features/step_definitions/gli_init_steps.rb
296
297
  - features/step_definitions/todo_steps.rb
297
298
  - features/support/env.rb
299
+ - features/support/hooks.rb
298
300
  - features/todo.feature
299
301
  - features/todo_legacy.feature
300
302
  - test/apps/README.md