commander-openflighthpc 1.0.0.pre.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +44 -0
  5. data/.rubocop_todo.yml +77 -0
  6. data/.travis.yml +14 -0
  7. data/CHANGELOG.md +5 -0
  8. data/Gemfile +3 -0
  9. data/LICENSE +51 -0
  10. data/Manifest +38 -0
  11. data/README.md +492 -0
  12. data/Rakefile +13 -0
  13. data/bin/commander +104 -0
  14. data/commander-openflighthpc.gemspec +32 -0
  15. data/lib/commander.rb +36 -0
  16. data/lib/commander/blank.rb +7 -0
  17. data/lib/commander/command.rb +263 -0
  18. data/lib/commander/configure.rb +14 -0
  19. data/lib/commander/core_ext.rb +2 -0
  20. data/lib/commander/core_ext/array.rb +24 -0
  21. data/lib/commander/core_ext/object.rb +8 -0
  22. data/lib/commander/delegates.rb +27 -0
  23. data/lib/commander/help_formatters.rb +52 -0
  24. data/lib/commander/help_formatters/base.rb +24 -0
  25. data/lib/commander/help_formatters/terminal.rb +24 -0
  26. data/lib/commander/help_formatters/terminal/command_help.erb +35 -0
  27. data/lib/commander/help_formatters/terminal/help.erb +36 -0
  28. data/lib/commander/help_formatters/terminal/subcommand_help.erb +23 -0
  29. data/lib/commander/help_formatters/terminal_compact.rb +11 -0
  30. data/lib/commander/help_formatters/terminal_compact/command_help.erb +26 -0
  31. data/lib/commander/help_formatters/terminal_compact/help.erb +29 -0
  32. data/lib/commander/help_formatters/terminal_compact/subcommand_help.erb +15 -0
  33. data/lib/commander/import.rb +5 -0
  34. data/lib/commander/methods.rb +11 -0
  35. data/lib/commander/patches/decimal-integer.rb +17 -0
  36. data/lib/commander/patches/help_formatter_binding.rb +15 -0
  37. data/lib/commander/patches/implicit-short-tags.rb +75 -0
  38. data/lib/commander/patches/option_defaults.rb +23 -0
  39. data/lib/commander/patches/validate_inputs.rb +76 -0
  40. data/lib/commander/platform.rb +7 -0
  41. data/lib/commander/runner.rb +493 -0
  42. data/lib/commander/user_interaction.rb +551 -0
  43. data/lib/commander/version.rb +3 -0
  44. data/spec/command_spec.rb +157 -0
  45. data/spec/configure_spec.rb +37 -0
  46. data/spec/core_ext/array_spec.rb +18 -0
  47. data/spec/core_ext/object_spec.rb +19 -0
  48. data/spec/help_formatters/terminal_compact_spec.rb +69 -0
  49. data/spec/help_formatters/terminal_spec.rb +67 -0
  50. data/spec/methods_spec.rb +61 -0
  51. data/spec/patches/validate_inputs_spec.rb +84 -0
  52. data/spec/runner_spec.rb +672 -0
  53. data/spec/spec_helper.rb +79 -0
  54. data/spec/ui_spec.rb +30 -0
  55. metadata +183 -0
@@ -0,0 +1,3 @@
1
+ module Commander
2
+ VERSION = '1.0.0-alpha1'.freeze
3
+ end
@@ -0,0 +1,157 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commander::Command do
4
+ include Commander::Methods
5
+
6
+ before :each do
7
+ mock_terminal
8
+ create_test_command
9
+ end
10
+
11
+ describe 'Options' do
12
+ before :each do
13
+ @options = Commander::Command::Options.new
14
+ end
15
+
16
+ it 'should act like an open struct' do
17
+ @options.send = 'mail'
18
+ @options.call = true
19
+ expect(@options.send).to eq('mail')
20
+ expect(@options.call).to eq(true)
21
+ end
22
+
23
+ it 'should allow __send__ to function as always' do
24
+ @options.send = 'foo'
25
+ expect(@options.__send__(:send)).to eq('foo')
26
+ end
27
+ end
28
+
29
+ describe '#option' do
30
+ it 'should add options' do
31
+ expect { @command.option '--recursive' }.to change(@command.options, :length).from(1).to(2)
32
+ end
33
+
34
+ it 'should allow procs as option handlers' do
35
+ @command.option('--recursive') { |recursive| expect(recursive).to be true }
36
+ @command.run '--recursive'
37
+ end
38
+
39
+ it 'should allow usage of common method names' do
40
+ @command.option '--open file'
41
+ @command.when_called { |_, options| expect(options.open).to eq('foo') }
42
+ @command.run '--open', 'foo'
43
+ end
44
+ end
45
+
46
+ describe '#run' do
47
+ describe 'should invoke #when_called' do
48
+ it 'with arguments seperated from options' do
49
+ @command.when_called { |args, _options| expect(args.join(' ')).to eq('just some args') }
50
+ @command.run '--verbose', 'just', 'some', 'args'
51
+ end
52
+
53
+ it 'calling the #call method by default when an object is called' do
54
+ object = double 'Object'
55
+ expect(object).to receive(:call).once
56
+ @command.when_called object
57
+ @command.run 'foo'
58
+ end
59
+
60
+ it 'should allow #action as an alias to #when_called' do
61
+ object = double 'Object'
62
+ expect(object).to receive(:call).once
63
+ @command.action object
64
+ @command.run 'foo'
65
+ end
66
+
67
+ it 'calling an arbitrary method when an object is called' do
68
+ object = double 'Object'
69
+ expect(object).to receive(:foo).once
70
+ @command.when_called object, :foo
71
+ @command.run 'foo'
72
+ end
73
+
74
+ it 'should raise an error when no handler is present' do
75
+ expect { @command.when_called }.to raise_error(ArgumentError)
76
+ end
77
+ end
78
+
79
+ describe 'should populate options with' do
80
+ it 'boolean values' do
81
+ @command.option '--[no-]toggle'
82
+ @command.when_called { |_, options| expect(options.toggle).to be true }
83
+ @command.run '--toggle'
84
+ @command.when_called { |_, options| expect(options.toggle).to be false }
85
+ @command.run '--no-toggle'
86
+ end
87
+
88
+ it 'mandatory arguments' do
89
+ @command.option '--file FILE'
90
+ @command.when_called { |_, options| expect(options.file).to eq('foo') }
91
+ @command.run '--file', 'foo'
92
+ expect { @command.run '--file' }.to raise_error(OptionParser::MissingArgument)
93
+ end
94
+
95
+ describe 'optional arguments' do
96
+ before do
97
+ @command.option '--use-config [file] '
98
+ end
99
+
100
+ it 'should return the argument when provided' do
101
+ @command.when_called { |_, options| expect(options.use_config).to eq('foo') }
102
+ @command.run '--use-config', 'foo'
103
+ end
104
+
105
+ it 'should return true when present without an argument' do
106
+ @command.when_called { |_, options| expect(options.use_config).to be true }
107
+ @command.run '--use-config'
108
+ end
109
+
110
+ it 'should return nil when not present' do
111
+ @command.when_called { |_, options| expect(options.use_config).to be_nil }
112
+ @command.run
113
+ end
114
+ end
115
+
116
+ describe 'typed arguments' do
117
+ before do
118
+ @command.option '--interval N', Integer
119
+ end
120
+
121
+ it 'should parse valid values' do
122
+ @command.when_called { |_, options| expect(options.interval).to eq(5) }
123
+ @command.run '--interval', '5'
124
+ end
125
+
126
+ it 'should reject invalid values' do
127
+ expect { @command.run '--interval', 'invalid' }.to raise_error(OptionParser::InvalidArgument)
128
+ end
129
+ end
130
+
131
+ it 'lists' do
132
+ @command.option '--fav COLORS', Array
133
+ @command.when_called { |_, options| expect(options.fav).to eq(%w(red green blue)) }
134
+ @command.run '--fav', 'red,green,blue'
135
+ end
136
+
137
+ it 'lists with multi-word items' do
138
+ @command.option '--fav MOVIES', Array
139
+ @command.when_called { |_, options| expect(options.fav).to eq(['super\ bad', 'nightmare']) }
140
+ @command.run '--fav', 'super\ bad,nightmare'
141
+ end
142
+
143
+ it 'defaults' do
144
+ @command.option '--files LIST', Array
145
+ @command.option '--interval N', Integer
146
+ @command.when_called do |_, options|
147
+ options.default \
148
+ files: %w(foo bar),
149
+ interval: 5
150
+ expect(options.files).to eq(%w(foo bar))
151
+ expect(options.interval).to eq(15)
152
+ end
153
+ @command.run '--interval', '15'
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ require 'commander/configure'
3
+
4
+ describe Commander do
5
+ describe '.configure' do
6
+ it 'calls the given block' do
7
+ expect { Commander.configure { throw :block_called } }.to throw_symbol(:block_called)
8
+ end
9
+
10
+ describe 'called block' do
11
+ before(:each) do
12
+ allow(Commander::Runner.instance).to receive(:run!)
13
+ end
14
+
15
+ it 'provides Commander configuration methods' do
16
+ Commander.configure do
17
+ program :name, 'test'
18
+ end
19
+
20
+ expect(Commander::Runner.instance.program(:name)).to eq('test')
21
+ end
22
+
23
+ it 'passes all arguments to the block' do
24
+ Commander.configure('foo') do |first_arg|
25
+ program :name, first_arg
26
+ end
27
+
28
+ expect(Commander::Runner.instance.program(:name)).to eq('foo')
29
+ end
30
+ end
31
+
32
+ it 'calls Runner#run! after calling the configuration block' do
33
+ expect(Commander::Runner.instance).to receive(:run!)
34
+ Commander.configure {}
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Array do
4
+ describe '#parse' do
5
+ it 'should seperate a list of words into an array' do
6
+ expect(Array.parse('just a test')).to eq(%w(just a test))
7
+ end
8
+
9
+ it 'should preserve escaped whitespace' do
10
+ expect(Array.parse('just a\ test')).to eq(['just', 'a test'])
11
+ end
12
+
13
+ it 'should match %w behavior with multiple backslashes' do
14
+ str = 'just a\\ test'
15
+ expect(Array.parse(str)).to eq(eval("%w(#{str})"))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Object do
4
+ describe '#get_binding' do
5
+ it 'should return the objects binding' do
6
+ expect(-> {}.get_binding).to be_instance_of(Binding)
7
+ end
8
+ end
9
+
10
+ describe '#method_missing' do
11
+ it 'should preserve its original behavior for missing methods' do
12
+ expect { send(:i_am_a_missing_method) }.to raise_error(NoMethodError)
13
+ end
14
+
15
+ it 'should preserve its original behavior for missing variables' do
16
+ expect { i_am_a_missing_variable }.to raise_error(NameError)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commander::HelpFormatter::TerminalCompact do
4
+ include Commander::Methods
5
+
6
+ before :each do
7
+ mock_terminal
8
+ end
9
+
10
+ describe 'global help' do
11
+ before :each do
12
+ new_command_runner 'help' do
13
+ program :help_formatter, :compact
14
+ command :'install gem' do |c|
15
+ c.syntax = 'foo install gem [options]'
16
+ c.summary = 'Install some gem'
17
+ end
18
+ end.run!
19
+ @global_help = @output.string
20
+ end
21
+
22
+ describe 'should display' do
23
+ it 'the command name' do
24
+ expect(@global_help).to include('install gem')
25
+ end
26
+
27
+ it 'the summary' do
28
+ expect(@global_help).to include('Install some gem')
29
+ end
30
+ end
31
+ end
32
+
33
+ describe 'command help' do
34
+ before :each do
35
+ new_command_runner 'help', 'install', 'gem' do
36
+ program :help_formatter, :compact
37
+ command :'install gem' do |c|
38
+ c.syntax = 'foo install gem [options]'
39
+ c.summary = 'Install some gem'
40
+ c.description = 'Install some gem, blah blah blah'
41
+ c.example 'one', 'two'
42
+ c.example 'three', 'four'
43
+ end
44
+ end.run!
45
+ @command_help = @output.string
46
+ end
47
+
48
+ describe 'should display' do
49
+ it 'the command name' do
50
+ expect(@command_help).to include('install gem')
51
+ end
52
+
53
+ it 'the description' do
54
+ expect(@command_help).to include('Install some gem, blah blah blah')
55
+ end
56
+
57
+ it 'all examples' do
58
+ expect(@command_help).to include('# one')
59
+ expect(@command_help).to include('two')
60
+ expect(@command_help).to include('# three')
61
+ expect(@command_help).to include('four')
62
+ end
63
+
64
+ it 'the syntax' do
65
+ expect(@command_help).to include('foo install gem [options]')
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commander::HelpFormatter::Terminal do
4
+ include Commander::Methods
5
+
6
+ before :each do
7
+ mock_terminal
8
+ end
9
+
10
+ describe 'global help' do
11
+ before :each do
12
+ new_command_runner 'help' do
13
+ command :'install gem' do |c|
14
+ c.syntax = 'foo install gem [options]'
15
+ c.summary = 'Install some gem'
16
+ end
17
+ end.run!
18
+ @global_help = @output.string
19
+ end
20
+
21
+ describe 'should display' do
22
+ it 'the command name' do
23
+ expect(@global_help).to include('install gem')
24
+ end
25
+
26
+ it 'the summary' do
27
+ expect(@global_help).to include('Install some gem')
28
+ end
29
+ end
30
+ end
31
+
32
+ describe 'command help' do
33
+ before :each do
34
+ new_command_runner 'help', 'install', 'gem' do
35
+ command :'install gem' do |c|
36
+ c.syntax = 'foo install gem [options]'
37
+ c.summary = 'Install some gem'
38
+ c.description = 'Install some gem, blah blah blah'
39
+ c.example 'one', 'two'
40
+ c.example 'three', 'four'
41
+ end
42
+ end.run!
43
+ @command_help = @output.string
44
+ end
45
+
46
+ describe 'should display' do
47
+ it 'the command name' do
48
+ expect(@command_help).to include('install gem')
49
+ end
50
+
51
+ it 'the description' do
52
+ expect(@command_help).to include('Install some gem, blah blah blah')
53
+ end
54
+
55
+ it 'all examples' do
56
+ expect(@command_help).to include('# one')
57
+ expect(@command_help).to include('two')
58
+ expect(@command_help).to include('# three')
59
+ expect(@command_help).to include('four')
60
+ end
61
+
62
+ it 'the syntax' do
63
+ expect(@command_help).to include('foo install gem [options]')
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require 'commander/methods'
3
+
4
+ describe Commander::Methods do
5
+ it 'includes Commander::UI' do
6
+ expect(subject.ancestors).to include(Commander::UI)
7
+ end
8
+
9
+ describe 'AskForClass' do
10
+ it 'includes Commander::UI::AskForClass' do
11
+ expect(subject.ancestors).to include(Commander::UI::AskForClass)
12
+ end
13
+
14
+ describe 'defining methods' do
15
+ let(:terminal) { double }
16
+
17
+ before do
18
+ allow(terminal).to receive(:ask)
19
+ $_old_terminal = $terminal
20
+ $terminal = terminal
21
+ end
22
+
23
+ after do
24
+ $terminal = $_old_terminal
25
+ end
26
+
27
+ subject do
28
+ Class.new do
29
+ include Commander::UI::AskForClass
30
+ end.new
31
+ end
32
+
33
+ it 'defines common "ask_for_*" methods' do
34
+ expect(subject.respond_to?(:ask_for_float)).to be_truthy
35
+ end
36
+
37
+ it 'responds to "ask_for_*" methods for classes that implement #parse' do
38
+ expect(subject.respond_to?(:ask_for_datetime)).to be_truthy
39
+ end
40
+
41
+ it 'fails "ask_for_*" method invocations without a prompt' do
42
+ expect do
43
+ subject.ask_for_datetime
44
+ end.to raise_error(ArgumentError)
45
+ end
46
+
47
+ it 'implements "ask_for_*"' do
48
+ expect(terminal).to receive(:ask)
49
+ subject.ask_for_datetime('hi')
50
+ end
51
+ end
52
+ end
53
+
54
+ it 'includes Commander::Delegates' do
55
+ expect(subject.ancestors).to include(Commander::Delegates)
56
+ end
57
+
58
+ it 'does not change the Object ancestors' do
59
+ expect(Object.ancestors).not_to include(Commander::UI)
60
+ end
61
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'commander/patches/validate_inputs'
4
+
5
+ # These specs inspired by those in Commander gem in `spec/runner_spec.rb`.
6
+
7
+ RSpec.describe Commander::Patches::ValidateInputs do
8
+ include Commander::Delegates
9
+
10
+ def mock_patch_terminal
11
+ @input = StringIO.new
12
+ @output = StringIO.new
13
+ $terminal = HighLine.new @input, @output
14
+ end
15
+
16
+ def create_test_patch_command
17
+ command :test do |c|
18
+ c.syntax = 'metal test ARG1 ARG2 [OPTIONAL_ARG3]'
19
+ c.description = 'test description'
20
+ c.example 'description', 'command'
21
+ c.option '-o', '--some-option', 'Some option that does things'
22
+ c.when_called do |args, _options|
23
+ format('test %<foo>s', foo: args.join(' '))
24
+ end
25
+ end
26
+ @command = command :test
27
+ end
28
+
29
+ def create_multi_word_test_command
30
+ command :'test do' do |c|
31
+ c.syntax = 'metal test do ARG1 ARG2'
32
+ c.when_called do |args, _options|
33
+ format('test do %<foo>s', foo: args.join(' '))
34
+ end
35
+ end
36
+ @command = command :'test do'
37
+ end
38
+
39
+ before do
40
+ $stderr = StringIO.new
41
+ mock_patch_terminal
42
+ create_test_patch_command
43
+ end
44
+
45
+ describe '#call' do
46
+ describe 'validating passed arguments against syntax' do
47
+ it 'raises if too many arguments given' do
48
+ expect do
49
+ command(:test).call(['one', 'two', 'three', 'four'])
50
+ end.to raise_error(Commander::Patches::CommandUsageError)
51
+ end
52
+
53
+ it 'raises if too few arguments given' do
54
+ expect do
55
+ command(:test).call(['one'])
56
+ end.to raise_error(Commander::Patches::CommandUsageError)
57
+ end
58
+
59
+ it 'proceeds as normal if valid number of arguments given' do
60
+ expect(
61
+ command(:test).call(['one', 'two', 'three'])
62
+ ).to eql('test one two three')
63
+ end
64
+
65
+ describe 'when multi-word command' do
66
+ before do
67
+ create_multi_word_test_command
68
+ end
69
+
70
+ it 'raises if too few arguments given' do
71
+ expect do
72
+ command(:'test do').call
73
+ end.to raise_error(Commander::Patches::CommandUsageError)
74
+ end
75
+
76
+ it 'proceeds as normal if valid number of arguments given' do
77
+ expect(
78
+ command(:'test do').call(['one', 'two'])
79
+ ).to eql('test do one two')
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end