aio_elin 0.0.1 → 1.0.0
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 +4 -4
- data/config.rb +32 -32
- data/lib/aio/base/toolkit/excel_wps.rb +1 -0
- data/lib/aio/base/toolkit/hash.rb +95 -0
- data/lib/aio/base/toolkit/myers.rb +161 -0
- data/lib/aio/base/toolkit.rb +2 -0
- data/lib/aio/core/device/cmd_switch.rb +1 -1
- data/lib/aio/core/device/h3c.rb +2 -0
- data/lib/aio/core/device/maipu.rb +8 -0
- data/lib/aio/core/device/methods.rb +230 -228
- data/lib/aio/core/device/parent_device.rb +270 -267
- data/lib/aio/core/device_manager.rb +255 -202
- data/lib/aio/core/module/cmd.rb +155 -150
- data/lib/aio/core/module/compare.rb +39 -0
- data/lib/aio/core/module/output_style.rb +2 -0
- data/lib/aio/core/module.rb +1 -0
- data/lib/aio/core/module_loader.rb +11 -0
- data/lib/aio/core/parse/file.rb +12 -14
- data/lib/aio/core/parse/parser.rb +99 -87
- data/lib/aio/core/parse/parser_machine/has_device_state.rb +42 -42
- data/lib/aio/core/parse/parser_machine.rb +44 -44
- data/lib/aio/core/text/block.rb +88 -0
- data/lib/aio/core/text/compare.rb +109 -0
- data/lib/aio/core/text/context.rb +206 -206
- data/lib/aio/core/text/line_string.rb +17 -62
- data/lib/aio/core/text/match_string_info.rb +73 -0
- data/lib/aio/core/text/warning.rb +175 -175
- data/lib/aio/core/text.rb +3 -0
- data/lib/aio/core/warning/warning_summarize.rb +246 -229
- data/lib/aio/core.rb +3 -0
- data/lib/aio/ui/logger.rb +38 -0
- data/lib/aio/ui/verbose.rb +6 -2
- data/lib/aio/ui.rb +135 -134
- data/lib/modules/cmd/cisco/show_version.rb +84 -84
- data/lib/modules/cmd/h3c/display_cpu.rb +41 -41
- data/lib/modules/cmd/h3c/display_version.rb +43 -43
- data/lib/modules/cmd/maipu/show_clock.rb +32 -0
- data/lib/modules/cmd/maipu/show_cpu.rb +36 -0
- data/lib/modules/cmd/maipu/show_ip_interface_brief.rb +44 -0
- data/lib/modules/cmd/maipu/show_memory.rb +22 -22
- data/lib/modules/cmd/maipu/show_version.rb +40 -40
- data/lib/modules/input/style/compare_xml.rb +73 -73
- data/lib/modules/output/style/cmds.rb +3 -3
- data/lib/modules/output/style/compare_diff.rb +23 -0
- data/lib/modules/output/style/excel_table_office.rb +1 -0
- data/lib/modules/output/style/excel_table_wps.rb +1 -0
- data/lib/modules/output/style/summary_report.rb +2 -1
- data/lib/modules/special/style/compare.rb +153 -103
- data/lib/modules/special/style/compare_old.rb +121 -0
- data/lib/modules/special/style/compare_with_device_manager.rb +227 -0
- metadata +16 -3
@@ -1,211 +1,211 @@
|
|
1
1
|
#coding=utf-8
|
2
2
|
|
3
3
|
module Aio::Text
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
4
|
+
class Context < ::Array
|
5
|
+
|
6
|
+
class OutLineError < StandardError; end
|
7
|
+
|
8
|
+
include Aio::Ui::Verbose
|
9
|
+
|
10
|
+
attr_reader :count_line, :backup_line
|
11
|
+
|
12
|
+
def initialize(*arr)
|
13
|
+
super
|
14
|
+
self.each_with_index do |str, i|
|
15
|
+
self[i] = Aio::Text::LineString.new(str.chomp)
|
16
|
+
end
|
17
|
+
@backup_line = nil
|
18
|
+
@count_line = 0
|
19
|
+
end
|
20
|
+
|
21
|
+
# 到下一行
|
22
|
+
def next
|
23
|
+
@count_line += 1
|
24
|
+
end
|
25
|
+
|
26
|
+
# 对每行进行read, 判断是单步运行还是循环运行
|
27
|
+
# 修改了此处的backup_line 逻辑
|
28
|
+
def readline_match_block(reg, single = false, &block)
|
29
|
+
|
30
|
+
reg = Aio::Base::Toolkit::Regexp.safe(reg)
|
31
|
+
|
32
|
+
first = true
|
33
|
+
loop do
|
34
|
+
line_str = self[@count_line]
|
35
|
+
|
36
|
+
if first
|
37
|
+
@backup_line = @count_line
|
38
|
+
end
|
39
|
+
|
40
|
+
# 如果出界,有可能是因为循环导致
|
41
|
+
# 跳出循环
|
42
|
+
# 此处有问题,无法判断是否为最后一个,并跳出此模块
|
43
|
+
if @backup_line > self.size and line_str.nil?
|
44
|
+
@count_line = @backup_line
|
45
|
+
if Aio::Base::Debug.mismatch?
|
46
|
+
puts "[-] Can't match this line: "
|
47
|
+
puts caller
|
48
|
+
puts " line_string: #{self[@backup_line]}"
|
49
|
+
puts " regexp: #{reg}"
|
50
|
+
end
|
51
|
+
raise OutLineError
|
52
|
+
end
|
53
|
+
|
54
|
+
if line_str.nil?
|
55
|
+
@count_line = @backup_line
|
56
|
+
break
|
57
|
+
end
|
58
|
+
|
59
|
+
first = false
|
60
|
+
begin
|
61
|
+
res = line_str.match_block(reg, self, @count_line) do |b|
|
62
|
+
block.call(b) unless block.nil?
|
63
|
+
end
|
64
|
+
rescue IndexError => e
|
65
|
+
print_error "IndexError: 请检查模块block提取信息名称"
|
66
|
+
puts "caller"
|
67
|
+
puts caller
|
68
|
+
exit
|
69
|
+
rescue NoMethodError
|
70
|
+
if Aio::Base::Debug.module_debug?
|
71
|
+
print_error "NoMethodError: 请检查模块block中useful是否定义正确"
|
72
|
+
puts caller
|
73
|
+
end
|
74
|
+
exit
|
75
|
+
rescue ArgumentError => e
|
76
|
+
if Aio::Base::Debug.module_debug?
|
77
|
+
puts "ArgumentError:"
|
78
|
+
puts e.message
|
79
|
+
puts caller
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
@count_line += 1
|
84
|
+
|
85
|
+
# 如果匹配到,跳出循环
|
86
|
+
break if res
|
87
|
+
|
88
|
+
# 如果只是单步运行,就返回
|
89
|
+
break if single
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# 单行循环
|
94
94
|
# stop 为停止出,在停止处之前的每一行都将输出
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
95
|
+
def readline_match_block_loop(start, stop, &block)
|
96
|
+
stop = Aio::Base::Toolkit::Regexp.safe(stop)
|
97
|
+
loop do
|
98
|
+
readline_match_block(start, true, &block)
|
99
|
+
break if stop.match(self[@count_line])
|
100
|
+
break if self[@count_line].nil?
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# 读取一个区间,并返回块
|
105
|
+
# 只会执行一次
|
106
|
+
# stop 作为分裂符
|
107
|
+
# opt 当last为false时,不会对stop一行输出
|
108
|
+
# opt 当before为true时,只会分裂stop的前一行,count_line保留
|
109
|
+
def readline_range(start, stop, opt={:last=>false}, &block)
|
110
|
+
str_context = Context.new
|
111
|
+
start = Aio::Base::Toolkit::Regexp.safe(start)
|
112
|
+
stop = Aio::Base::Toolkit::Regexp.safe(stop)
|
113
|
+
backup_line = @count_line
|
114
|
+
|
115
|
+
loop do
|
116
|
+
line_str = self[@count_line]
|
117
|
+
|
118
|
+
if line_str.nil?
|
119
|
+
@count_line = backup_line
|
120
|
+
raise OutLineError
|
121
|
+
end
|
122
|
+
|
123
|
+
if start =~ line_str
|
124
|
+
str_context << line_str
|
125
|
+
@count_line += 1
|
126
|
+
break
|
127
|
+
end
|
128
|
+
@count_line += 1
|
129
|
+
end
|
130
|
+
|
131
|
+
loop do
|
132
|
+
line_str = self[@count_line]
|
133
|
+
#raise OutLineError if line_str.nil?
|
134
|
+
if stop =~ line_str or line_str.nil?
|
135
|
+
str_context << line_str if opt[:last]
|
136
|
+
@count_line += 1 unless opt[:before]
|
137
|
+
break
|
138
|
+
else
|
139
|
+
str_context << line_str
|
140
|
+
end
|
141
|
+
@count_line += 1
|
142
|
+
end
|
143
|
+
|
144
|
+
block.call(str_context)
|
145
|
+
end
|
146
|
+
|
147
|
+
# 当需要多次循环时使用
|
148
|
+
# 此方法用于循环更加安全
|
149
|
+
def readline_range_loop(start, stop, opt={:last=>false}, &block)
|
150
|
+
loop do
|
151
|
+
begin
|
152
|
+
readline_range(start, stop, opt, &block)
|
153
|
+
rescue OutLineError
|
154
|
+
break
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# 读取一个区间并返回块
|
160
|
+
# 在起始位置之后的行中,满足条件, 则放入同一区间。否则返回
|
161
|
+
def readline_range_if(start, condition, &block)
|
162
|
+
str_context = Context.new
|
163
|
+
start = Aio::Base::Toolkit::Regexp.safe(start)
|
164
|
+
condition = Aio::Base::Toolkit::Regexp.safe(condition)
|
165
|
+
|
166
|
+
loop do
|
167
|
+
line_str = self[@count_line]
|
168
|
+
raise OutLineError if line_str.nil?
|
169
|
+
if start =~ line_str
|
170
|
+
str_context << line_str
|
171
|
+
@count_line += 1
|
172
|
+
break
|
173
|
+
end
|
174
|
+
@count_line += 1
|
175
|
+
end
|
176
|
+
|
177
|
+
loop do
|
178
|
+
line_str = self[@count_line]
|
179
|
+
if condition =~ line_str
|
180
|
+
str_context << line_str
|
181
|
+
@count_line += 1
|
182
|
+
else
|
183
|
+
break
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
block.call(str_context)
|
188
|
+
end
|
189
|
+
|
190
|
+
def readline_range_if_loop(start, condition, &block)
|
191
|
+
loop do
|
192
|
+
begin
|
193
|
+
readline_range_if(start, condition, &block)
|
194
|
+
rescue OutLineError
|
195
|
+
break
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def count_line
|
201
|
+
self[@count_line]
|
202
|
+
end
|
203
|
+
|
204
|
+
def method_missing(mid, *arg, &block)
|
205
|
+
print_error "#{mid} 方法未定义,请检查方法名拼写"
|
206
|
+
puts caller[0]
|
207
|
+
super
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
211
|
end
|
@@ -1,74 +1,29 @@
|
|
1
1
|
#coding=utf-8
|
2
2
|
|
3
3
|
module Aio::Text
|
4
|
-
|
5
|
-
|
4
|
+
class LineString < String
|
5
|
+
class Mismatch < StandardError; end
|
6
6
|
|
7
|
-
|
7
|
+
attr_accessor :content, :line
|
8
8
|
|
9
|
-
|
10
|
-
def match_block(reg)
|
11
|
-
block = reg.match(self)
|
12
|
-
#raise Mismatch.new, "reg: #{reg}\nstr: #{self.to_s}" if block.nil?
|
13
|
-
if block.nil?
|
14
|
-
return false
|
15
|
-
end
|
9
|
+
include Aio::Ui::Verbose
|
16
10
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
11
|
+
# 获得区块
|
12
|
+
# 并且获得所在的行数
|
13
|
+
def match_block(reg, cont, line)
|
14
|
+
block = Block.new(reg.match(self))
|
15
|
+
#raise Mismatch.new, "reg: #{reg}\nstr: #{self.to_s}" if block.nil?
|
16
|
+
if block.nil?
|
17
|
+
return false
|
18
|
+
end
|
25
19
|
|
26
|
-
|
27
|
-
|
28
|
-
else
|
29
|
-
info[sym] = str.strip
|
30
|
-
end
|
31
|
-
end
|
20
|
+
block.content = cont
|
21
|
+
block.line = line
|
32
22
|
|
33
|
-
|
34
|
-
|
35
|
-
info[sym] ||= []
|
36
|
-
info[sym] << self[sym].strip
|
37
|
-
end
|
23
|
+
yield block
|
24
|
+
end
|
38
25
|
|
39
|
-
def block.update_hash(info, sym, key, val)
|
40
|
-
sym = sym.to_sym
|
41
|
-
info[sym] ||= {}
|
42
|
-
info[sym][key] = val.strip
|
43
|
-
end
|
44
26
|
|
45
|
-
|
46
|
-
# 参数sym 为Symbol类型的标示
|
47
|
-
# 参数level 为 :serious 或 :ordinary
|
48
|
-
# 参数mod 一般为self
|
49
|
-
# 参数opt[:string] 当block中没有sym项时使用
|
50
|
-
def block.warning(info, sym, level, mod, opt={})
|
51
|
-
sym = sym.to_sym
|
52
|
-
self.update(info, sym, opt[:string])
|
53
|
-
# Aio::Text::Warning 类中的warning方法
|
54
|
-
mod.warning_klass.warning(info, sym, level, mod, opt[:force])
|
55
|
-
end
|
56
|
-
|
57
|
-
def block.warning_serious(info, sym, mod, opt={})
|
58
|
-
sym = sym.to_sym
|
59
|
-
self.update(info, sym, opt[:string])
|
60
|
-
mod.warning_klass.warning_serious(info, sym, mod, opt[:force])
|
61
|
-
end
|
62
|
-
|
63
|
-
def block.warning_ordinary(info, sym, mod, opt={})
|
64
|
-
sym = sym.to_sym
|
65
|
-
self.update(info, sym, opt[:string])
|
66
|
-
mod.warning_klass.warning_ordinary(info, sym, mod, opt[:force])
|
67
|
-
end
|
68
|
-
|
69
|
-
yield block
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
27
|
+
end
|
73
28
|
end
|
74
29
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Aio::Text
|
2
|
+
|
3
|
+
# 将提取的关键信息附带的增加所在上下文以及行数
|
4
|
+
class MatchStringInfo < Struct.new(:var, :content, :line)
|
5
|
+
|
6
|
+
# 存放比较后的不同值,也是 MachStringInfo 类
|
7
|
+
attr_accessor :compare_val
|
8
|
+
|
9
|
+
def initialize(var, content, line)
|
10
|
+
super(
|
11
|
+
var,
|
12
|
+
content,
|
13
|
+
line
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
var.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
var
|
23
|
+
end
|
24
|
+
|
25
|
+
# 覆盖原有的eql?
|
26
|
+
def eql?(other_match)
|
27
|
+
self.to_s.eql?(other_match.to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
# 判断和另一个class是否是同一个content
|
31
|
+
def same_content?(other_match)
|
32
|
+
content == other_match.content
|
33
|
+
end
|
34
|
+
|
35
|
+
# 判断是否和另一个值为同一行
|
36
|
+
def same_line?(other_match)
|
37
|
+
if same_content?
|
38
|
+
return line == other_match.line
|
39
|
+
end
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
|
43
|
+
# 判断是否有compare_val值
|
44
|
+
def compare_val?
|
45
|
+
!@compare_val.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
# 差异值的文本
|
49
|
+
def compare_content
|
50
|
+
compare_val.content
|
51
|
+
end
|
52
|
+
|
53
|
+
# 差异值的行数
|
54
|
+
def compare_line
|
55
|
+
compare_val.line
|
56
|
+
end
|
57
|
+
|
58
|
+
def var; self[:var].to_s; end
|
59
|
+
def content; self[:content]; end
|
60
|
+
def line; self[:line]; end
|
61
|
+
|
62
|
+
def method_missing(m, *args)
|
63
|
+
if var.respond_to?(m)
|
64
|
+
var.send(m, *args)
|
65
|
+
|
66
|
+
else
|
67
|
+
super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|