noir 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/noir/executer.rb +44 -23
- data/lib/noir/version.rb +1 -1
- data/spec/noir/command/completion_spec.rb +2 -0
- data/spec/noir/executer_spec.rb +47 -7
- data/spec/spec_helper.rb +19 -15
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 321b15d42d793bbc446da53068990490c43d1d53
|
4
|
+
data.tar.gz: 958e080bde8a7e4aba828cef99ad0587b774b869
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 047e554c78f92f237badf491e967d86c8a8af8edb89938f0cc9350dc1c39376f2e7d841dd6481fb648aee8107ba65f10b0c7ac6b823bbcd3e9c54e99d34477ee
|
7
|
+
data.tar.gz: fc30d7f7a8890a13a01fafeca7ec82e1a8984b044224c83cb003ce86136008ac9ecec46833e8898c4540574186be68eb8bb54a23f153ce286fdac7747e5bde85
|
data/lib/noir/executer.rb
CHANGED
@@ -1,33 +1,52 @@
|
|
1
1
|
module Noir
|
2
2
|
class Executer
|
3
3
|
|
4
|
+
# utils
|
5
|
+
|
6
|
+
def self.find_command command_arr, search_str
|
7
|
+
command = eval(command_arr.join('::'))
|
8
|
+
|
9
|
+
# finish find by terminal command
|
10
|
+
return nil if command.superclass == Noir::Base::TerminalCommand
|
11
|
+
|
12
|
+
commands = command.constants(true).map(&:to_s)
|
13
|
+
matched_str = commands.find{|c| c.downcase == search_str.downcase}
|
14
|
+
matched_str = find_abbr_command(commands, search_str) if matched_str.nil?
|
15
|
+
|
16
|
+
return nil if matched_str.nil?
|
17
|
+
matched_arr = command_arr + [matched_str]
|
18
|
+
unless eval(matched_arr.join('::')).ancestors.include?(Noir::Base::Command)
|
19
|
+
# matched. but matched class is not inherited commmand
|
20
|
+
return nil
|
21
|
+
end
|
22
|
+
|
23
|
+
return matched_str
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.find_abbr_command commands, search_str
|
27
|
+
# abbrev match
|
28
|
+
matched_commands = commands.select{|c| c.downcase.start_with? search_str}
|
29
|
+
|
30
|
+
return nil if matched_commands.empty?
|
31
|
+
unless matched_commands.size == 1
|
32
|
+
raise "#{search_str} is ambiguous. matched #{matched_commands}"
|
33
|
+
end
|
34
|
+
|
35
|
+
matched_commands.first
|
36
|
+
end
|
37
|
+
|
4
38
|
def self.command_from_argv
|
5
39
|
args = ARGV.clone
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
if matched_command = noir_commands.find{|c| c.downcase == arg.downcase}
|
14
|
-
|
15
|
-
command_arr << matched_command
|
16
|
-
command = eval(command_arr.join('::'))
|
17
|
-
if command.superclass == Noir::Base::Command
|
18
|
-
noir_commands = command.constants(true).map(&:to_s) # search next command in sub class
|
19
|
-
elsif command.superclass == Noir::Base::TerminalCommand
|
20
|
-
break # search finished by terminal command
|
21
|
-
else
|
22
|
-
command_arr.pop
|
23
|
-
# delete last matched_command, because this class is not inherited Noir::Base::Command
|
24
|
-
command = eval(command_arr.join('::'))
|
25
|
-
break
|
26
|
-
end
|
27
|
-
end
|
40
|
+
command_arr = ['Noir', 'Command'] # command prefix and default command
|
41
|
+
|
42
|
+
while true
|
43
|
+
break unless search_str = args.shift
|
44
|
+
break unless matched_command = find_command(command_arr, search_str)
|
45
|
+
|
46
|
+
command_arr << matched_command
|
28
47
|
end
|
29
48
|
|
30
|
-
return
|
49
|
+
return eval(command_arr.join('::'))
|
31
50
|
end
|
32
51
|
|
33
52
|
def self.args_from_argv
|
@@ -38,6 +57,8 @@ module Noir
|
|
38
57
|
return argv.drop(command_size)
|
39
58
|
end
|
40
59
|
|
60
|
+
# inherited methods
|
61
|
+
|
41
62
|
def self.execute
|
42
63
|
command_from_argv.execute *args_from_argv
|
43
64
|
end
|
data/lib/noir/version.rb
CHANGED
@@ -14,6 +14,7 @@ describe 'Noir::Command::Completion' do
|
|
14
14
|
it 'return all command from nil' do
|
15
15
|
expect(Noir::Command::Completion.suggestions([])).to include('hoge')
|
16
16
|
expect(Noir::Command::Completion.suggestions([])).to include('fuga')
|
17
|
+
expect(Noir::Command::Completion.suggestions([])).to include('fugafuga')
|
17
18
|
end
|
18
19
|
|
19
20
|
it 'return nil from unmatched pattern' do
|
@@ -24,6 +25,7 @@ describe 'Noir::Command::Completion' do
|
|
24
25
|
list = ['h']
|
25
26
|
expect(Noir::Command::Completion.suggestions(list)).to include('hoge')
|
26
27
|
expect(Noir::Command::Completion.suggestions(list)).to_not include('fuga')
|
28
|
+
expect(Noir::Command::Completion.suggestions(list)).to_not include('fugafuga')
|
27
29
|
end
|
28
30
|
|
29
31
|
it 'return command list in sub command' do
|
data/spec/noir/executer_spec.rb
CHANGED
@@ -23,15 +23,21 @@ describe 'Noir::Executer' do
|
|
23
23
|
it 'return Noir::Command' do
|
24
24
|
expect(Noir::Executer.command_from_argv).to eq(Noir::Command)
|
25
25
|
end
|
26
|
-
end
|
26
|
+
end # in undefined ARGV
|
27
27
|
|
28
|
-
describe 'in defined
|
28
|
+
describe 'in defined ARGV' do
|
29
29
|
|
30
30
|
it 'return command' do
|
31
31
|
stub_const 'ARGV', ['hoge']
|
32
32
|
expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge)
|
33
33
|
end
|
34
34
|
|
35
|
+
it 'return prefix duplicated command' do
|
36
|
+
stub_const 'ARGV', ['fuga']
|
37
|
+
expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Fuga)
|
38
|
+
expect(Noir::Executer.command_from_argv).not_to eq(Noir::Command::FugaFuga)
|
39
|
+
end
|
40
|
+
|
35
41
|
it 'return command if has other arguments' do
|
36
42
|
stub_const 'ARGV', ['hoge', 'aaa']
|
37
43
|
expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge)
|
@@ -77,8 +83,41 @@ describe 'Noir::Executer' do
|
|
77
83
|
expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Fuga)
|
78
84
|
end
|
79
85
|
|
86
|
+
describe 'abbrev command' do
|
87
|
+
|
88
|
+
it 'return only matched command' do
|
89
|
+
stub_const 'ARGV', ['ho']
|
90
|
+
expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'raise exception matched one more' do
|
94
|
+
stub_const 'ARGV', ['h']
|
95
|
+
expect{Noir::Executer.command_from_argv}.to raise_error
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'support multi command abbrev' do
|
99
|
+
stub_const 'ARGV', ['ho', 'subcommandt']
|
100
|
+
expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge::SubCommandTwo)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'support multi command abbrev with args' do
|
104
|
+
stub_const 'ARGV', ['ho', 'subcommandt', 'piyo']
|
105
|
+
expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge::SubCommandTwo)
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end # in defined ARGV
|
110
|
+
end # command_from_argv
|
111
|
+
|
112
|
+
describe 'find_command' do
|
113
|
+
it 'return perfect matched command' do
|
114
|
+
expect(Noir::Executer.find_command ['Noir', 'Command'], 'hoge').to eq('Hoge')
|
80
115
|
end
|
81
|
-
|
116
|
+
|
117
|
+
it 'raise exeption in ambiguous match' do
|
118
|
+
expect{Noir::Executer.find_command(['Noir', 'Command'], 'f')}.to raise_error
|
119
|
+
end
|
120
|
+
end # find_command
|
82
121
|
|
83
122
|
describe 'args_from_argv' do
|
84
123
|
|
@@ -88,9 +127,9 @@ describe 'Noir::Executer' do
|
|
88
127
|
it 'return []' do
|
89
128
|
expect(Noir::Executer.args_from_argv).to eq([])
|
90
129
|
end
|
91
|
-
end
|
130
|
+
end # in undefined ARGV
|
92
131
|
|
93
|
-
describe 'in defined
|
132
|
+
describe 'in defined ARGV' do
|
94
133
|
|
95
134
|
it 'return [] if only command' do
|
96
135
|
stub_const 'ARGV', ['hoge']
|
@@ -162,6 +201,7 @@ describe 'Noir::Executer' do
|
|
162
201
|
expect(Noir::Executer.args_from_argv).to eq(['aaa', 'bbb'])
|
163
202
|
end
|
164
203
|
|
165
|
-
end
|
166
|
-
|
204
|
+
end # in defined argv
|
205
|
+
|
206
|
+
end # args_from_argv
|
167
207
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -12,26 +12,30 @@ def stub_commands
|
|
12
12
|
stub_const('Noir::Command::Hoge::SubCommandTwo' , Class.new(Noir::Base::Command))
|
13
13
|
stub_const('Noir::Command::Hoge::SubNonCommand' , Class.new)
|
14
14
|
stub_const('Noir::Command::Fuga' , Class.new(Noir::Base::TerminalCommand))
|
15
|
+
stub_const('Noir::Command::FugaFuga' , Class.new(Noir::Base::TerminalCommand))
|
15
16
|
|
17
|
+
# stub_const is this structure
|
16
18
|
=begin
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
class SubSubCommand < Noir::Base::Command
|
22
|
-
end
|
23
|
-
class SubSubNonCommand
|
24
|
-
end
|
25
|
-
end
|
26
|
-
class SubCommandTwo < Noir::Base::Command
|
27
|
-
end
|
28
|
-
|
29
|
-
class SubNonCommand
|
30
|
-
end
|
19
|
+
class Noir::Command
|
20
|
+
class Hoge < Noir::Base::Command
|
21
|
+
class SubCommand < Noir::Base::Command
|
22
|
+
class SubSubCommand < Noir::Base::Command
|
31
23
|
end
|
32
|
-
class
|
24
|
+
class SubSubNonCommand
|
33
25
|
end
|
34
26
|
end
|
27
|
+
|
28
|
+
class SubCommandTwo < Noir::Base::Command
|
29
|
+
end
|
30
|
+
|
31
|
+
class SubNonCommand
|
32
|
+
end
|
33
|
+
end
|
34
|
+
class Fuga < Noir::Base::TerminalCommand
|
35
|
+
end
|
36
|
+
class Fuga < Noir::Base::TerminalCommand
|
37
|
+
end
|
38
|
+
end
|
35
39
|
=end
|
36
40
|
|
37
41
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: noir
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- atton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|