gli 2.11.0 → 2.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +28 -0
  3. data/.gitignore +3 -3
  4. data/.tool-versions +1 -0
  5. data/Gemfile +0 -2
  6. data/README.rdoc +29 -19
  7. data/Rakefile +15 -37
  8. data/bin/ci +29 -0
  9. data/bin/gli +24 -54
  10. data/bin/rake +29 -0
  11. data/bin/setup +5 -0
  12. data/exe/gli +68 -0
  13. data/gli.gemspec +20 -24
  14. data/gli.rdoc +9 -9
  15. data/lib/gli/app.rb +31 -8
  16. data/lib/gli/app_support.rb +15 -3
  17. data/lib/gli/command.rb +24 -2
  18. data/lib/gli/command_finder.rb +42 -25
  19. data/lib/gli/command_support.rb +7 -6
  20. data/lib/gli/commands/doc.rb +9 -3
  21. data/lib/gli/commands/help.rb +2 -1
  22. data/lib/gli/commands/help_modules/arg_name_formatter.rb +2 -2
  23. data/lib/gli/commands/help_modules/command_help_format.rb +19 -1
  24. data/lib/gli/commands/help_modules/full_synopsis_formatter.rb +3 -2
  25. data/lib/gli/commands/help_modules/global_help_format.rb +1 -1
  26. data/lib/gli/commands/help_modules/options_formatter.rb +4 -6
  27. data/lib/gli/commands/initconfig.rb +3 -6
  28. data/lib/gli/commands/rdoc_document_listener.rb +2 -1
  29. data/lib/gli/commands/scaffold.rb +71 -142
  30. data/lib/gli/dsl.rb +2 -1
  31. data/lib/gli/flag.rb +23 -2
  32. data/lib/gli/gli_option_parser.rb +66 -15
  33. data/lib/gli/option_parser_factory.rb +9 -2
  34. data/lib/gli/options.rb +2 -2
  35. data/lib/gli/switch.rb +4 -0
  36. data/lib/gli/terminal.rb +6 -2
  37. data/lib/gli/version.rb +1 -1
  38. data/lib/gli.rb +1 -0
  39. data/object-model.dot +29 -0
  40. data/object-model.png +0 -0
  41. data/test/apps/todo/Gemfile +1 -1
  42. data/test/apps/todo/bin/todo +12 -6
  43. data/test/apps/todo/lib/todo/commands/create.rb +42 -41
  44. data/test/apps/todo/lib/todo/commands/list.rb +48 -36
  45. data/test/apps/todo/lib/todo/commands/ls.rb +25 -24
  46. data/test/apps/todo/lib/todo/commands/make.rb +42 -39
  47. data/test/apps/todo/todo.gemspec +1 -2
  48. data/test/apps/todo_legacy/todo.gemspec +1 -2
  49. data/test/apps/todo_plugins/commands/third.rb +2 -0
  50. data/test/integration/gli_cli_test.rb +69 -0
  51. data/test/integration/gli_powered_app_test.rb +52 -0
  52. data/test/integration/scaffold_test.rb +30 -0
  53. data/test/integration/test_helper.rb +52 -0
  54. data/test/unit/command_finder_test.rb +54 -0
  55. data/test/{tc_command.rb → unit/command_test.rb} +20 -7
  56. data/test/unit/compound_command_test.rb +17 -0
  57. data/test/{tc_doc.rb → unit/doc_test.rb} +38 -51
  58. data/test/{tc_flag.rb → unit/flag_test.rb} +19 -25
  59. data/test/{tc_gli.rb → unit/gli_test.rb} +78 -50
  60. data/test/{tc_help.rb → unit/help_test.rb} +54 -113
  61. data/test/{tc_options.rb → unit/options_test.rb} +4 -4
  62. data/test/unit/subcommand_parsing_test.rb +263 -0
  63. data/test/unit/subcommands_test.rb +245 -0
  64. data/test/{config.yaml → unit/support/gli_test_config.yml} +1 -0
  65. data/test/unit/switch_test.rb +49 -0
  66. data/test/{tc_terminal.rb → unit/terminal_test.rb} +28 -3
  67. data/test/unit/test_helper.rb +13 -0
  68. data/test/unit/verbatim_wrapper_test.rb +24 -0
  69. metadata +85 -141
  70. data/.ruby-gemset +0 -1
  71. data/.ruby-version +0 -1
  72. data/.travis.yml +0 -12
  73. data/ObjectModel.graffle +0 -1191
  74. data/bin/report_on_rake_results +0 -10
  75. data/bin/test_all_rubies.sh +0 -6
  76. data/features/gli_executable.feature +0 -90
  77. data/features/gli_init.feature +0 -232
  78. data/features/step_definitions/gli_executable_steps.rb +0 -18
  79. data/features/step_definitions/gli_init_steps.rb +0 -11
  80. data/features/step_definitions/todo_steps.rb +0 -100
  81. data/features/support/env.rb +0 -55
  82. data/features/todo.feature +0 -546
  83. data/features/todo_legacy.feature +0 -128
  84. data/test/option_test_helper.rb +0 -13
  85. data/test/tc_compound_command.rb +0 -22
  86. data/test/tc_subcommand_parsing.rb +0 -104
  87. data/test/tc_subcommands.rb +0 -259
  88. data/test/tc_switch.rb +0 -55
  89. data/test/tc_verbatim_wrapper.rb +0 -36
  90. data/test/test_helper.rb +0 -20
  91. /data/test/{init_simplecov.rb → unit/init_simplecov.rb} +0 -0
  92. /data/test/{fake_std_out.rb → unit/support/fake_std_out.rb} +0 -0
@@ -0,0 +1,245 @@
1
+ require_relative "test_helper"
2
+ require_relative "support/fake_std_out"
3
+
4
+ class SubcommandsTest < MiniTest::Test
5
+ include TestHelper
6
+
7
+ def setup
8
+ @fake_stdout = FakeStdOut.new
9
+ @fake_stderr = FakeStdOut.new
10
+
11
+ @original_stdout = $stdout
12
+ $stdout = @fake_stdout
13
+ @original_stderr = $stderr
14
+ $stderr = @fake_stderr
15
+
16
+ @app = CLIApp.new
17
+ @app.reset
18
+ @app.subcommand_option_handling :legacy
19
+ @app.error_device=@fake_stderr
20
+ ENV.delete('GLI_DEBUG')
21
+ end
22
+
23
+ def teardown
24
+ $stdout = @original_stdout
25
+ $stderr = @original_stderr
26
+ end
27
+
28
+ def test_we_run_add_command_using_add
29
+ we_have_a_command_with_two_subcommands
30
+ run_app('remote',"add",'-f','foo','bar')
31
+ assert_command_ran_with(:add, :command_options => {:f => true}, :args => %w(foo bar))
32
+ end
33
+ def test_we_run_add_command_using_new
34
+ we_have_a_command_with_two_subcommands
35
+ run_app('remote',"new",'-f','foo','bar')
36
+ assert_command_ran_with(:add, :command_options => {:f => true}, :args => %w(foo bar))
37
+ end
38
+
39
+ def test_subcommands_not_used_on_command_line_uses_base_action
40
+ we_have_a_command_with_two_subcommands
41
+ run_app('remote','foo','bar')
42
+ assert_command_ran_with(:base, :command_options => {:f => false}, :args => %w(foo bar))
43
+ end
44
+
45
+ def test_switches_and_flags_on_subcommand_available
46
+ we_have_a_command_with_two_subcommands(:switches => [:addswitch], :flags => [:addflag])
47
+ run_app('remote','add','--addswitch','--addflag','foo','bar')
48
+ assert_command_ran_with(:add,:command_options => { :addswitch => true, :addflag => 'foo', :f => false },
49
+ :args => ['bar'])
50
+ end
51
+
52
+ def test_help_flag_works_in_normal_mode
53
+ @app.subcommand_option_handling :normal
54
+ we_have_a_command_with_two_subcommands
55
+ @app.run(["remote", "add", "--help"]) rescue nil
56
+ refute_match /^error/, @fake_stderr.to_s, "should not output an error message"
57
+ end
58
+
59
+ def test_help_flag_works_in_legacy_mode
60
+ @app.subcommand_option_handling :legacy
61
+ we_have_a_command_with_two_subcommands
62
+ @app.run(["remote", "add", "--help"]) rescue nil
63
+ refute_match /^error/, @fake_stderr.to_s, "should not output an error message"
64
+ end
65
+
66
+ def test_we_can_reopen_commands_to_add_new_subcommands
67
+ @app.command :remote do |p|
68
+ p.command :add do |c|
69
+ c.action do |global_options,command_options,args|
70
+ @ran_command = :add
71
+ end
72
+ end
73
+ end
74
+ @app.command :remote do |p|
75
+ p.command :new do |c|
76
+ c.action do |global_options,command_options,args|
77
+ @ran_command = :new
78
+ end
79
+ end
80
+ end
81
+ run_app('remote','new')
82
+ assert_equal(@ran_command, :new)
83
+ run_app('remote', 'add')
84
+ assert_equal(@ran_command, :add)
85
+ end
86
+
87
+ def test_reopening_commands_doesnt_readd_to_output
88
+ @app.command :remote do |p|
89
+ p.command(:add) { }
90
+ end
91
+ @app.command :remote do |p|
92
+ p.command(:new) { }
93
+ end
94
+ command_names = @app.instance_variable_get("@commands_declaration_order").collect { |c| c.name }
95
+ assert_equal 1, command_names.grep(:remote).size
96
+ end
97
+
98
+
99
+ def test_we_can_reopen_commands_without_causing_conflicts
100
+ @app.command :remote do |p|
101
+ p.command :add do |c|
102
+ c.action do |global_options,command_options,args|
103
+ @ran_command = :remote_add
104
+ end
105
+ end
106
+ end
107
+ @app.command :local do |p|
108
+ p.command :add do |c|
109
+ c.action do |global_options,command_options,args|
110
+ @ran_command = :local_add
111
+ end
112
+ end
113
+ end
114
+ run_app('remote','add')
115
+ assert_equal(@ran_command, :remote_add)
116
+ run_app('local', 'add')
117
+ assert_equal(@ran_command, :local_add)
118
+ end
119
+
120
+
121
+ def test_we_can_nest_subcommands_very_deep
122
+ @run_results = { :add => nil, :rename => nil, :base => nil }
123
+ @app.command :remote do |c|
124
+
125
+ c.switch :f
126
+ c.command :add do |add|
127
+ add.command :some do |some|
128
+ some.command :cmd do |cmd|
129
+ cmd.switch :s
130
+ cmd.action do |global_options,command_options,args|
131
+ @run_results[:cmd] = [global_options,command_options,args]
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ ENV['GLI_DEBUG'] = 'true'
138
+ run_app('remote','add','some','cmd','-s','blah')
139
+ assert_command_ran_with(:cmd, :command_options => {:s => true, :f => false},:args => ['blah'])
140
+ end
141
+
142
+ def test_when_any_command_has_no_action_but_there_are_args_indicate_unknown_command
143
+ a_very_deeply_nested_command_structure
144
+ assert_raises GLI::UnknownCommand do
145
+ When run_app('remote','add','some','foo')
146
+ end
147
+ assert_match /Unknown command 'foo'/,@fake_stderr.to_s
148
+ end
149
+
150
+ def test_when_any_command_has_no_action_but_there_are_no_args_indicate_subcommand_needed
151
+ a_very_deeply_nested_command_structure
152
+ assert_raises GLI::BadCommandLine do
153
+ When run_app('remote','add','some')
154
+ end
155
+ assert_match /Command 'some' requires a subcommand/,@fake_stderr.to_s
156
+ end
157
+
158
+ private
159
+
160
+ def run_app(*args)
161
+ @exit_code = @app.run(args)
162
+ end
163
+
164
+ def a_very_deeply_nested_command_structure
165
+ @run_results = { :add => nil, :rename => nil, :base => nil }
166
+ @app.command :remote do |c|
167
+
168
+ c.switch :f
169
+ c.command :add do |add|
170
+ add.command :some do |some|
171
+ some.command :cmd do |cmd|
172
+ cmd.switch :s
173
+ cmd.action do |global_options,command_options,args|
174
+ @run_results[:cmd] = [global_options,command_options,args]
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+ ENV['GLI_DEBUG'] = 'true'
181
+ end
182
+
183
+ # expected_command - name of command exepcted to have been run
184
+ # options:
185
+ # - global_options => hash of expected options
186
+ # - command_options => hash of expected command options
187
+ # - args => array of expected args
188
+ def assert_command_ran_with(expected_command,options)
189
+ global_options = options[:global_options] || { :help => false }
190
+ @run_results.each do |command,results|
191
+ if command == expected_command
192
+ assert_equal(indifferent_hash(global_options),results[0])
193
+ assert_equal(indifferent_hash(options[:command_options]),results[1])
194
+ assert_equal(options[:args],results[2])
195
+ else
196
+ assert_nil results
197
+ end
198
+ end
199
+ end
200
+
201
+ def indifferent_hash(possibly_nil_hash)
202
+ return {} if possibly_nil_hash.nil?
203
+ possibly_nil_hash.keys.each do |key|
204
+ if key.kind_of? Symbol
205
+ possibly_nil_hash[key.to_s] = possibly_nil_hash[key] unless possibly_nil_hash.has_key?(key.to_s)
206
+ elsif key.kind_of? String
207
+ possibly_nil_hash[key.to_sym] = possibly_nil_hash[key] unless possibly_nil_hash.has_key?(key.to_sym)
208
+ end
209
+ end
210
+ possibly_nil_hash
211
+ end
212
+
213
+ # options -
214
+ # :flags => flags to add to :add
215
+ # :switiches => switiches to add to :add
216
+ def we_have_a_command_with_two_subcommands(options = {})
217
+ @run_results = { :add => nil, :rename => nil, :base => nil }
218
+ @app.command :remote do |c|
219
+
220
+ c.switch :f
221
+
222
+ c.desc "add a remote"
223
+ c.command [:add,:new] do |add|
224
+
225
+ Array(options[:flags]).each { |_| add.flag _ }
226
+ Array(options[:switches]).each { |_| add.switch _ }
227
+ add.action do |global_options,command_options,args|
228
+ @run_results[:add] = [global_options,command_options,args]
229
+ end
230
+ end
231
+
232
+ c.desc "rename a remote"
233
+ c.command :rename do |rename|
234
+ rename.action do |global_options,command_options,args|
235
+ @run_results[:rename] = [global_options,command_options,args]
236
+ end
237
+ end
238
+
239
+ c.action do |global_options,command_options,args|
240
+ @run_results[:base] = [global_options,command_options,args]
241
+ end
242
+ end
243
+ ENV['GLI_DEBUG'] = 'true'
244
+ end
245
+ end
@@ -8,3 +8,4 @@ commands:
8
8
  :f: barfoo
9
9
  :f: foo
10
10
  :bleorgh: true
11
+ :t: false
@@ -0,0 +1,49 @@
1
+ require_relative "test_helper"
2
+
3
+ class SwitchTest < MiniTest::Test
4
+ include TestHelper
5
+
6
+ def test_basics_simple
7
+ switch_with_names(:filename)
8
+ attributes_should_be_set
9
+ assert_equal(:filename,@cli_option.name)
10
+ assert_nil @cli_option.aliases
11
+ end
12
+
13
+ def test_basics_kinda_complex
14
+ switch_with_names([:f])
15
+ attributes_should_be_set
16
+ assert_equal(:f,@cli_option.name)
17
+ assert_nil @cli_option.aliases
18
+ end
19
+
20
+ def test_basics_complex
21
+ switch_with_names([:f,:file,:filename])
22
+ attributes_should_be_set
23
+ assert_equal(:f,@cli_option.name)
24
+ assert_equal([:file,:filename],@cli_option.aliases)
25
+ assert_equal ["-f","--[no-]file","--[no-]filename"],@switch.arguments_for_option_parser
26
+ end
27
+
28
+ def test_includes_negatable
29
+ assert_equal '-a',GLI::Switch.name_as_string('a')
30
+ assert_equal '--[no-]foo',GLI::Switch.name_as_string('foo')
31
+ end
32
+
33
+ private
34
+
35
+ def switch_with_names(names)
36
+ @options = {
37
+ :desc => 'Filename',
38
+ :long_desc => 'The Filename',
39
+ }
40
+ @switch = GLI::Switch.new(names,@options)
41
+ @cli_option = @switch
42
+ end
43
+
44
+ def attributes_should_be_set
45
+ assert_equal(@options[:desc],@switch.description)
46
+ assert_equal(@options[:long_desc],@switch.long_description)
47
+ end
48
+
49
+ end
@@ -1,9 +1,10 @@
1
- require 'test_helper'
1
+ require_relative "test_helper"
2
2
 
3
- class TC_testTerminal < Clean::Test::TestCase
3
+ class TerminalTest < MiniTest::Test
4
4
  include TestHelper
5
5
 
6
- def test_command_exists
6
+ # TODO: Make this test not mess with the internals of the class
7
+ def xtest_command_exists
7
8
  assert GLI::Terminal.instance.command_exists?('ls')
8
9
  assert !GLI::Terminal.instance.command_exists?('asdfasfasdf')
9
10
  end
@@ -73,6 +74,30 @@ class TC_testTerminal < Clean::Test::TestCase
73
74
  assert_equal [5678,1234],terminal.size
74
75
  end
75
76
 
77
+ def test_size_using_stty_but_returns_0
78
+ terminal = GLI::Terminal.new
79
+ terminal.make_unsafe!
80
+ GLI::Terminal.instance_eval do
81
+ def run_command(command)
82
+
83
+ if RUBY_PLATFORM == 'java'
84
+ return '0' if command == 'tput cols'
85
+ return '0' if command == 'tput lines'
86
+ else
87
+ return '0 0' if command == 'stty size'
88
+ return '0 0' if command == 'stty'
89
+ end
90
+
91
+ raise "Unexpected command called: #{command} for #{RUBY_PLATFORM}"
92
+ end
93
+ def command_exists?(command); true; end
94
+ def jruby?; false; end
95
+ def solaris?; false; end
96
+ end
97
+ ENV['COLUMNS'] = 'foo'
98
+ assert_equal [80,24],terminal.size
99
+ end
100
+
76
101
  def test_size_using_default
77
102
  terminal = GLI::Terminal.new
78
103
  terminal.make_unsafe!
@@ -0,0 +1,13 @@
1
+ require "minitest/autorun"
2
+ require "gli"
3
+
4
+ module TestHelper
5
+ class CLIApp
6
+ include GLI::App
7
+
8
+ def reset
9
+ super
10
+ @subcommand_option_handling_strategy = :normal
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ require_relative "test_helper"
2
+
3
+ class TerminalTest < MiniTest::Test
4
+ include TestHelper
5
+
6
+ def test_handles_nil
7
+ @wrapper = GLI::Commands::HelpModules::VerbatimWrapper.new(rand(100),rand(100))
8
+ @result = @wrapper.wrap(nil)
9
+ assert_equal '',@result
10
+ end
11
+
12
+ def test_does_not_touch_input
13
+ @wrapper = GLI::Commands::HelpModules::VerbatimWrapper.new(rand(100),rand(100))
14
+ @input = <<EOS
15
+ |This is|an ASCII|table|
16
+ +-------+--------+-----+
17
+ | foo | bar | baz |
18
+ +-------+--------+-----+
19
+ EOS
20
+ @result = @wrapper.wrap(@input)
21
+ assert_equal @input,@result
22
+ end
23
+
24
+ end