commander-openflighthpc 1.0.0.pre.alpha1

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.
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