ymlex 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
- metadata.gz: d58cf8e6242857ce7733c5c3fb8c7e6943e36fff
4
- data.tar.gz: 788e86d712d1aa6224a58430edd155241f9a6903
3
+ metadata.gz: 08193ba23283d08722054a4aeb4e727b366c33e1
4
+ data.tar.gz: 36a6458002ac1726f5b8110a1c6f2565530c0ba2
5
5
  !binary "U0hBNTEy":
6
- metadata.gz: a8998586d0251f20a9f1dc5410b1fecc70934533b406ec1a88a0cfa4abede86f54a40fe3fa2bc0e6c01a8ccbe631f8afc972e69d9d6fe121c1ce04ab33d84294
7
- data.tar.gz: e92d59c7b104c9406fec09c89b23e9ab135bfb8264cbe0aed1e2852099e909109fefba1ce1bb064520fca0fe9c5874711ffd8b47cbe98fefcaebaf19da47c8e7
6
+ metadata.gz: 27558b9ac2e0139539676232418c3654103249c1d186c84d089472bef087115e655016e82f40e409b757d90429d1a6bf5cc855021925c9c408ee3b3bc36a365a
7
+ data.tar.gz: 6dc301b9d99f40b8ba104d3ffb2c854baf3684e095c2299ff6d12cf21431bdf3c5ab038167ebe3ab585460c799889f02cde8d96b322e353c50263e5ddea30bd5
data/bin/ymlex ADDED
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ home = File.join(File.dirname(__FILE__),'..')
4
+ $LOAD_PATH.unshift(File.join(home,'lib'))
5
+
6
+ require 'ymlex'
7
+
8
+ def find_last
9
+ pwd = Dir.pwd
10
+ last = nil
11
+ dir = nil
12
+ until last or pwd == ""
13
+ file = "#{pwd}/.ymlex.last"
14
+ if File.exist? file
15
+ File.open file, "r" do |f|
16
+ last = f.read.chomp
17
+ dir = pwd
18
+ end
19
+ end
20
+ pwd = pwd.sub(/\/(\w)*$/,"")
21
+ end
22
+ [last, dir]
23
+ end
24
+
25
+ options = {}
26
+ OptionParser.new do |opts|
27
+ opts.banner = "Usage: ymlex [options]"
28
+ opts.on("-t", "--template [directory]", "Path to template, default is './'") do |template_dir|
29
+ options[:template] = template_dir
30
+ Ymlex.initTptDir template_dir
31
+ end
32
+ opts.on("-p", "--product [directoy]", "Translate a directiory of ymlex files") do |product_dir|
33
+ options[:product] = product_dir
34
+ end
35
+ opts.on("-j", "--[no-]show-json", "Show the instance in json") do
36
+ options[:showjson] = true
37
+ end
38
+ opts.on("-y", "--[no-]show-yml", "Show the instance in yaml") do
39
+ options[:showyml] = true
40
+ end
41
+ opts.on("-c", "--ci [product]", "check in") do |product|
42
+ product, options[:pwd] = find_last if !product
43
+ options[:ci] = product
44
+ end
45
+ opts.on("-n", "--new [modu]", "check in") do |modu|
46
+ options[:new] = modu
47
+ end
48
+ opts.on("-a", "--auto [product]", "Trans product automatically") do |product|
49
+ product, options[:pwd] = find_last if !product
50
+ options[:auto] = product
51
+ end
52
+ opts.on("-o", "--output [directory]", "Set output directory") do |output_dir|
53
+ options[:output] = output_dir
54
+ end
55
+ opts.on("-l", "--log [log_name]", "Trans log monitor") do |log_name|
56
+ options[:log] = log_name
57
+ end
58
+ opts.on("-h", "--help", "Show this help") do
59
+ puts opts
60
+ exit
61
+ end
62
+ end.parse!
63
+ options[:output] = options[:auto] || "./output" if !options[:output]
64
+
65
+ case
66
+ when options[:new]
67
+ modu = options[:new]
68
+ file = <<HD_NEW
69
+ name: #{modu}
70
+ # node:
71
+ # - BAIDU_ECOM_SDC_SOMENODE
72
+ # bns:
73
+ # - somebns
74
+ contacts:
75
+ rd: ""
76
+ op: ""
77
+ qa: ""
78
+ basepath: /home/work/#{modu}
79
+ _inherit: c_base.tpt
80
+ request:
81
+ listen:
82
+ port: 8080
83
+ proc:
84
+ main:
85
+ path: ${basepath}/bin/#{modu}
86
+ log:
87
+ accessLog:
88
+ path: ${basepath}/log/#{modu}.log
89
+ flow:
90
+ formula: ${self}_cps >= 1000
91
+ errorLog:
92
+ path: ${basepath}/log/#{modu}.log.wf
93
+ fatal:
94
+ match_str: FATAL
95
+ formula: ${self}_cnt > 1
96
+ # aggr:
97
+ # flow_sum:
98
+ # items: #{modu}_log_accessLog_flow_cps
99
+ # types: sum
100
+ HD_NEW
101
+ File.open "#{modu}.yex", "w" do |f|
102
+ f.write file
103
+ end
104
+ exit
105
+ when options[:ci]
106
+ git_product = options[:ci]
107
+ svn_product = git_product.upcase
108
+ local_path = options[:pwd] || options[:output]
109
+ git_path = "#{local_path}/git/#{git_product}"
110
+ svn_path = "#{local_path}/svn/#{svn_product}"
111
+ system <<HD_SHELL_CI
112
+ set -eu
113
+ echo "svn check in ..."
114
+ cd #{svn_path} && svn ci -m 'auto check in'
115
+ echo "git commit and push ..."
116
+ cd #{git_path} && git add . && git commit -am 'auto commit' && git push
117
+ HD_SHELL_CI
118
+ exit
119
+ when options[:log]
120
+ filename = options[:log]
121
+ log_js = {}
122
+ File.open(filename,"r") do |f|
123
+ log_js = JSON.parse f.read
124
+ end
125
+ log_yml = {}
126
+ log_yml["path"] = log_js["log_filepath"]
127
+ log_js["item"].each do |item|
128
+ name = item["item_name_prefix"]
129
+ item.delete "item_name_prefix"
130
+ log_yml[name] = item
131
+ end
132
+ puts log_yml.to_yaml
133
+ exit
134
+ when options[:auto]
135
+ git_product = options[:auto]
136
+ svn_product = git_product.upcase
137
+ git_remote = "http://gitlab.baidu.com/sdc-monitor/#{git_product}.git"
138
+ template_remote = "http://gitlab.baidu.com/sdc-monitor/template.git"
139
+ svn_remote = "http://svn.noah.baidu.com/svn/conf/online/#{svn_product}"
140
+ local_path = options[:pwd] || options[:output]
141
+ git_path = "#{local_path}/git/#{git_product}"
142
+ template_path = "#{local_path}/git/template"
143
+ svn_path = "#{local_path}/svn/#{svn_product}"
144
+ system <<HD_SHELL
145
+ set -eu
146
+ mkdir -p #{local_path}/git #{local_path}/svn
147
+ echo #{git_product} > #{local_path}/.ymlex.last
148
+ if [[ -d #{git_path} ]]; then
149
+ echo "#{git_path} exist. git pull ..."
150
+ cd #{git_path}
151
+ git pull
152
+ cd -
153
+ else
154
+ echo "#{git_path} not exist. git clone ..."
155
+ cd #{local_path}/git
156
+ git clone #{git_remote}
157
+ cd -
158
+ fi
159
+ if [[ -d #{template_path} ]]; then
160
+ echo "#{template_path} exist. git pull ..."
161
+ cd #{template_path}
162
+ git pull
163
+ cd -
164
+ else
165
+ echo "#{template_path} not exist. git clone ..."
166
+ cd #{local_path}/git
167
+ git clone #{template_remote}
168
+ cd -
169
+ fi
170
+ if [[ -d #{svn_path} ]]; then
171
+ echo "#{svn_path} exist. svn up ..."
172
+ cd #{svn_path}
173
+ svn up
174
+ cd -
175
+ else
176
+ echo "#{svn_path} not exist. svn co ..."
177
+ cd #{local_path}/svn
178
+ svn co #{svn_remote}
179
+ cd -
180
+ fi
181
+ echo "process ymlex ..."
182
+ ymlex -p #{git_path} -t #{template_path} -o #{svn_path}
183
+ cd #{svn_path}
184
+ echo "show svn diff"
185
+ svn st | grep '?' | awk '{print $2}' | xargs svn add || true
186
+ svn st | grep '!' | awk '{print $2}' | xargs svn delete || true
187
+ svn diff
188
+ HD_SHELL
189
+ puts <<HD_SHELL
190
+ ==================================================================
191
+ output is in #{svn_path}, you may check in after comfirm the diff:
192
+ cd #{svn_path}
193
+ svn ci
194
+ HD_SHELL
195
+ exit
196
+ when options[:product]
197
+ ArgusYml.process_dir options[:product], options[:output]
198
+ else
199
+ until ARGV.empty?
200
+ input = ARGV.shift
201
+ ags = ArgusYml.new input
202
+ puts ags.info_yml.to_yaml if options[:showyml]
203
+ puts JSON.pretty_generate ags.instance if options[:showjson]
204
+ ags.dump_json options[:output] if options[:output]
205
+ end
206
+ end
@@ -0,0 +1,380 @@
1
+ #!/usr/bin/env ruby
2
+ class Alert
3
+ # level definition
4
+ # nil: no alert
5
+ # info: mail
6
+ # warning: summury and sms
7
+ # error: sms
8
+ # fatal: sms to boss
9
+ attr :contacts, :default_level
10
+ def initialize contacts, level={}
11
+ @contacts = contacts
12
+ @default_level = { "oncall" => "g_ecomop_maop_oncall",
13
+ "manager" => "g_ecomop_maop_manager",
14
+ "rd" => "err",
15
+ "op" => "warn",
16
+ "qa" => nil }.merge(level)
17
+ end
18
+
19
+ def get_alert lvl={}
20
+ level = @default_level.merge(lvl)
21
+ oncall = level["oncall"]
22
+ manager = level["manager"]
23
+
24
+ mail = ""
25
+ sms = ""
26
+ level.each do |role, lvl|
27
+ if ["op","rd","qa"].include? role
28
+ mail = "#{@contacts[role]};#{mail}" if lvl != nil
29
+ if lvl =~ /err/ or lvl =~ /fatal/ or (lvl =~ /warn/ and role != "op")
30
+ sms = "#{@contacts[role]};#{sms}"
31
+ end
32
+ end
33
+ end
34
+ lvl = level["op"]
35
+ sms = "#{oncall};#{sms}" if lvl =~ /warn/ or lvl =~ /err/ or lvl =~ /fatal/
36
+ sms = "#{manager};#{sms}" if lvl =~ /fatal/
37
+
38
+ remind_time = (lvl =~ /fatal/)? "300" : "7200"
39
+ alt = {
40
+ "max_alert_times" => level["max_alert_times"] || "2",
41
+ "alert_threshold_percent" => level["alert_threshold_percent"] || "0",
42
+ "sms_threshold_percent" => level["sms_threshold_percent"] || "0",
43
+ "remind_interval_second" => level["remind_interval_second"] || remind_time,
44
+ "mail" => mail,
45
+ "sms" => sms,
46
+ }
47
+ if lvl =~ /warn/
48
+ alt["level1_upgrade_interval"] = "10800"
49
+ alt["level1_upgrade_sms"] = @contacts["op"]
50
+ if manager != ""
51
+ alt["level2_upgrade_interval"] = "36000"
52
+ alt["level2_upgrade_sms"] = manager
53
+ end
54
+ end
55
+ if lvl =~ /err/ and manager != ""
56
+ alt["level1_upgrade_interval"] = "10800"
57
+ alt["level1_upgrade_sms"] = manager
58
+ end
59
+ alt
60
+ end
61
+
62
+ def get_mail lvl=nil
63
+ alert_info = get_alert lvl
64
+ alert_info["mail"]
65
+ end
66
+
67
+ def get_sms lvl=nil
68
+ alert_info = get_alert lvl
69
+ alert_info["sms"]
70
+ end
71
+
72
+ end
73
+
74
+ class ArgusYml
75
+
76
+ def self.process_dir dir_path, dest_path, product = nil
77
+ filelist = `find #{dir_path} -type f -name '*yex'`.split(' ')
78
+ product = File.basename dir_path if !product
79
+ filelist.each do |ymx|
80
+ puts "process #{ymx}"
81
+ ags = ArgusYml.new ymx, product
82
+ ags.dump_json dest_path
83
+ end
84
+ end
85
+
86
+ attr_reader :info_yml, :instance, :logs, :name, :bns, :alert, :node
87
+
88
+ def initialize filename_or_hash, product = nil
89
+ if filename_or_hash.kind_of? String
90
+ yml = Ymlex.load_file filename_or_hash
91
+ else
92
+ yml = filename_or_hash
93
+ end
94
+ @info_yml = value_to_str yml
95
+ @name = @info_yml["name"]
96
+ @bns = @info_yml["bns"] || []
97
+ node_list = @info_yml["node"] || []
98
+ node_str = ""
99
+ node_list.each {|v| node_str += v + ","}
100
+ @node = node_str.sub /,$/, ""
101
+ @product = product || @info_yml["product"] || @bns.first.sub(/^.*?\./,"").sub(/\..*$/,"") || "Undefined_Product"
102
+ @logs = {}
103
+ @alert = Alert.new @info_yml["contacts"], @info_yml["alert"]
104
+ @service_aggr = []
105
+ @service_rule = []
106
+ @service_alert = [default_alert]
107
+ reset_instance
108
+ trans_ytoj
109
+ end
110
+
111
+ def reset_instance
112
+ @instance = empty
113
+ end
114
+
115
+ def value_to_str input
116
+ case
117
+ when input.kind_of?(Hash)
118
+ input.each do |k,v|
119
+ input[k] = value_to_str v
120
+ end
121
+ when input.kind_of?(Array)
122
+ input.each_index do |i|
123
+ input[i] = value_to_str input[i]
124
+ end
125
+ when input.kind_of?(Fixnum) || input.kind_of?(Float)
126
+ input = input.to_s
127
+ end
128
+ input
129
+ end
130
+
131
+ def dump_json dir_path, append_mode = true
132
+
133
+ dir = "#{dir_path}/cluster/cluster.#{@name}.#{@product}.all"
134
+ `mkdir -p #{dir}`
135
+
136
+ # instance
137
+ filename = "#{dir}/instance"
138
+ if append_mode
139
+ old_instance = nil
140
+ begin
141
+ File.open(filename,"r") do |f|
142
+ old_instance = JSON.parse f.read
143
+ end
144
+ old_instance = empty if !old_instance
145
+ rescue
146
+ old_instance = empty
147
+ end
148
+ new_instance = {}
149
+ ["raw","request","rule","alert"].each do |type|
150
+ new_instance[type] = old_instance[type]
151
+ next unless @instance[type]
152
+ @instance[type].each do |new_item|
153
+ idx = old_instance[type].find_index do |old_item|
154
+ old_item["name"] == new_item["name"]
155
+ end
156
+ if idx
157
+ new_instance[type][idx] = new_item
158
+ else
159
+ new_instance[type] << new_item
160
+ end
161
+ end
162
+ end
163
+ else
164
+ new_instance = @instance
165
+ end
166
+ File.open(filename,"w") do |f|
167
+ f.puts JSON.pretty_generate new_instance
168
+ end
169
+
170
+ # log
171
+ @logs.each do |log_key, log_value|
172
+ log_name = "#{dir}/#{log_key}.conf"
173
+ File.open(log_name, "w") do |f|
174
+ f.puts JSON.pretty_generate log_value
175
+ end
176
+ end
177
+
178
+ # cluster
179
+ aggr_name = "#{dir}/cluster"
180
+ File.open(aggr_name, "w") do |f|
181
+ cluster = { "aggr" => @service_aggr,
182
+ "rule" => @service_rule,
183
+ "alert" => @service_alert,
184
+ }
185
+ cluster["namespace_list"] = @bns if @bns != []
186
+ cluster["service_node"] = @node if @node != ""
187
+ f.puts JSON.pretty_generate cluster
188
+ end
189
+ end
190
+
191
+ def trans_ytoj
192
+ @info_yml.each do |key, value|
193
+ case key
194
+ when "proc"
195
+ trans_proc value
196
+ when "request"
197
+ trans_request value
198
+ when "exec"
199
+ trans_exec value
200
+ when "other"
201
+ trans_other value
202
+ when "log"
203
+ trans_log value
204
+ when "aggr"
205
+ trans_aggr value
206
+ end
207
+ end
208
+ end
209
+
210
+ def trans_aggr list
211
+ list.each do | rule_name, value |
212
+ @service_aggr << { "items" => value["items"],
213
+ "types" => value["types"] || "sum",
214
+ }
215
+ if value["formula"]
216
+ rule_name = "#{@name}_aggr_#{rule_name}"
217
+ alert_name = "default_alert"
218
+ if value["alert"]
219
+ alt = @alert.get_alert value["alert"]
220
+ alt["name"] = rule_name
221
+ @service_alert << alt
222
+ alert_name = rule_name
223
+ end
224
+ @service_rule << { "name" => rule_name,
225
+ "formula" => value["formula"],
226
+ "filter" => value["filter"] || "1/1",
227
+ "alert" => alert_name }
228
+ end
229
+ end
230
+ end
231
+
232
+ def trans_exec list
233
+ list.each do | raw_key, raw_value |
234
+ dft_exec_raw = { "cycle" => "60",
235
+ "method" => "exec",
236
+ }
237
+ raw_value["name"] = "#{@name}_exec_#{raw_key}"
238
+ @instance["raw"] << dft_exec_raw.merge(raw_value)
239
+ end
240
+ end
241
+
242
+ def trans_other list
243
+ list.each do | rule_key, rule_value |
244
+ rule_name = "#{@name}_other_#{rule_key}"
245
+ alert_name = "default_alert"
246
+ if rule_value["alert"]
247
+ alt = @alert.get_alert rule_value["alert"]
248
+ alt["name"] = rule_name
249
+ @instance["alert"] << alt
250
+ alert_name = rule_name
251
+ end
252
+ @instance["rule"] << { "name" => rule_name,
253
+ "formula" => rule_value["formula"],
254
+ "filter" => rule_value["filter"] || "1/1",
255
+ "alert" => alert_name }
256
+ end
257
+ end
258
+
259
+ def trans_log list
260
+ list.each do |log_key, log_value|
261
+ raw_name = "#{@name}_log_#{log_key}"
262
+ log_raw = { "name" => raw_name,
263
+ "cycle" => log_value["cycle"] || "60",
264
+ "method" => "noah",
265
+ "target" => "logmon",
266
+ "params" => "${ATTACHMENT_DIR}/#{raw_name}.conf",
267
+ }
268
+ @instance["raw"] << log_raw
269
+
270
+ log_conf = { "log_filepath" => log_value["path"],
271
+ "limit_rate" => "5",
272
+ "item" => []
273
+ }
274
+ log_value.each do |raw_key, raw_value|
275
+ next if raw_key == "path"
276
+ item_name_prefix = "#{raw_name}_#{raw_key}"
277
+ item = { "item_name_prefix" => item_name_prefix,
278
+ "cycle" => raw_value["cycle"] || "60",
279
+ "match_str" => raw_value["match_str"],
280
+ "filter_str" => raw_value["filter_str"] || "",
281
+ }
282
+ log_conf["item"] << item
283
+ next unless raw_value["formula"]
284
+ alert_name = "default_alert"
285
+ if raw_value["alert"]
286
+ alt = @alert.get_alert raw_value["alert"]
287
+ alt["name"] = item_name_prefix
288
+ @instance["alert"] << alt
289
+ alert_name = item_name_prefix
290
+ end
291
+ @instance["rule"] << { "name" => item_name_prefix,
292
+ "formula" => raw_value["formula"],
293
+ "filter" => raw_value["filter"] || "1/1",
294
+ "alert" => alert_name,
295
+ }
296
+ end
297
+ @logs[raw_name] = log_conf
298
+ end
299
+ end
300
+
301
+ def trans_proc list
302
+ list.each do |raw_key, raw_value|
303
+ raw_name = "#{@name}_proc_#{raw_key}"
304
+ @instance["raw"] << { "name" => raw_name,
305
+ "cycle" => raw_value["cycle"]||"60",
306
+ "method" => "noah",
307
+ "target" => "procmon",
308
+ "params" => raw_value["path"] }
309
+ raw_value.each do |rule_key, rule_value|
310
+ next if (rule_key == "path" || !rule_value["formula"])
311
+ rule_name = "#{raw_name}_#{rule_key}"
312
+ alert_name = "default_alert"
313
+ if rule_value["alert"]
314
+ alt = @alert.get_alert rule_value["alert"]
315
+ alt["name"] = rule_name
316
+ @instance["alert"] << alt
317
+ alert_name = rule_name
318
+ end
319
+ @instance["rule"] << { "name" => rule_name,
320
+ "formula" => rule_value["formula"],
321
+ "filter" => rule_value["filter"]||"3/3",
322
+ "alert" => alert_name }
323
+ end
324
+ end
325
+ end
326
+
327
+ def trans_request list
328
+ list.each do |raw_key, raw_value|
329
+ raw_name = "#{@name}_request_#{raw_key}"
330
+ dft_raw = { "name" => raw_name,
331
+ "cycle" => "60",
332
+ "port" => "8080",
333
+ "protocol" => "tcp",
334
+ "mon_idc" => "local",
335
+ "req_type" => "port",
336
+ }
337
+ @instance["request"] << dft_raw.merge(raw_value)
338
+ alert_name = "default_alert"
339
+ if raw_value["alert"]
340
+ alt = @alert.get_alert raw_value["alert"]
341
+ alt["name"] = raw_name
342
+ @instance["alert"] << alt
343
+ alert_name = raw_name
344
+ end
345
+ @instance["rule"] << { "name" => raw_name,
346
+ "formula" => "#{raw_name} != 'ok'",
347
+ "filter" => raw_value["filter"]||"3/3",
348
+ "alert" => alert_name }
349
+ end
350
+ end
351
+
352
+ private
353
+
354
+ def noah_error
355
+ {
356
+ "name" => "noah_error",
357
+ "formula" => "noah_error != '' && not_contain(noah_error,'logmon open log failed') && time_between('080000-220000')",
358
+ "filter" => "100/100",
359
+ "alert" => "noah_error_alert",
360
+ }
361
+ end
362
+
363
+ def default_alert
364
+ alt = @alert.get_alert
365
+ alt["name"] = "default_alert"
366
+ alt
367
+ end
368
+
369
+ def noah_error_alert
370
+ alt = @alert.get_alert({"rd" => nil, "qa" => nil, "op" => "warn" })
371
+ alt["name"] = "noah_error_alert"
372
+ alt
373
+ end
374
+
375
+ def empty
376
+ {"raw"=>[], "request"=>[], "rule"=>[noah_error], "alert"=>[default_alert,noah_error_alert]}
377
+ end
378
+
379
+ end
380
+
data/lib/ymlex/ymlex.rb CHANGED
@@ -3,6 +3,8 @@
3
3
  class Ymlex
4
4
 
5
5
  @log = Logger.new STDOUT
6
+ @log.level = Logger::WARN
7
+ @name = nil
6
8
 
7
9
  def self.initLogger logger
8
10
  @log = logger
@@ -21,13 +23,23 @@ class Ymlex
21
23
  end
22
24
 
23
25
  def self.load_file file
24
- @log.debug "start load file: #{file}"
26
+ loadFile file
27
+ end
28
+
29
+ def self.loadFile file
25
30
  input = YAML.load_file file
26
- @tptDir ||= File.dirname file
31
+ @name = input["name"] || nil
32
+ @pwd = File.dirname file
33
+ @tptDir ||= @pwd
27
34
  input = parse input
28
- @log.debug "after parse, #{file} is #{input}"
29
35
  input = verblize input
30
- @log.debug "after verblize, #{file} is #{input}"
36
+ input
37
+ end
38
+
39
+ def self.loadTpt file
40
+ input = YAML.load_file file
41
+ @tptDir ||= File.dirname file
42
+ input = parse input
31
43
  input
32
44
  end
33
45
 
@@ -38,36 +50,46 @@ class Ymlex
38
50
  end
39
51
  end
40
52
  if input.key? "_inherit"
41
- father = load_file File.join(@tptDir,input["_inherit"])
53
+ if File.exist? File.join(@pwd,input["_inherit"])
54
+ father = loadTpt File.join(@pwd,input["_inherit"])
55
+ elsif File.exist? File.join(@tptDir,input["_inherit"])
56
+ father = loadTpt File.join(@tptDir,input["_inherit"])
57
+ end
42
58
  input.delete "_inherit"
43
59
  input = merge father, input
44
60
  end
45
61
  input
46
62
  end
47
63
 
48
- def self.verblize input, ref = nil
64
+ def self.verblize input, ref = nil, selfRule = nil
49
65
  ref ||= input
50
- case
66
+ case
51
67
  when input.class == Hash
52
68
  input.each do |key,value|
53
- input[key] = verblize value, ref
69
+ nextRule = selfRule ? "#{selfRule}_#{key}" : key
70
+ input[key] = verblize value, ref, nextRule
54
71
  end
55
72
  when input.class == Array
56
73
  input.each_index do |i|
57
- input[i] = verblize input[i], ref
74
+ input[i] = verblize input[i], ref, selfRule
58
75
  end
59
76
  when input.class == String
60
- input = verbString input, ref
77
+ input = verbString input, ref, selfRule
61
78
  end
62
79
  input
63
80
  end
64
81
 
65
- def self.verbString input, ref
82
+ def self.verbString input, ref, selfRule
83
+ selfRule = selfRule.sub(/^/, "#{@name}_") if @name
84
+ selfRule = selfRule.sub(/_[a-zA-Z0-9]*$/, '')
85
+ selfRule = selfRule.sub(/_[a-zA-Z0-9]*$/, '') if selfRule =~ /_proc_/
86
+ input = input.gsub(/[\$@]{self}/, selfRule)
87
+
66
88
  reg = /\${(.*?)}/.match(input)
67
89
  while reg
68
- toRep = reg[1] if reg
90
+ toRep = reg[1]
69
91
  toEval = toRep.gsub(/[\.]/,"\"][\"").sub(/^/,"ref[\"").sub(/$/,"\"]")
70
- begin
92
+ begin
71
93
  resultEval = eval toEval
72
94
  rescue
73
95
  @log.error "fail to verbString #{input}"
@@ -76,6 +98,16 @@ class Ymlex
76
98
  input = input.sub(/\${(.*?)}/,resultEval)
77
99
  reg = /\${(.*?)}/.match(input)
78
100
  end
101
+
102
+ reg = /@{(.*?)}/.match(input)
103
+ while reg
104
+ toRep = reg[1]
105
+ keyStr = toRep.gsub(/\./, '_')
106
+ keyStr = keyStr.sub(/^/, "#{@name}_") if @name
107
+ input = input.sub(/@{(.*?)}/, keyStr)
108
+ reg = /\${(.*?)}/.match(input)
109
+ end
110
+
79
111
  input
80
112
  end
81
113
 
@@ -86,13 +118,15 @@ class Ymlex
86
118
  father[key] = merge value, child[key]
87
119
  elsif value.class == Array && child[key].class == Array
88
120
  father[key] = (value + child[key]).uniq
121
+ elsif child[key] == "disable"
122
+ father.delete key
89
123
  else
90
124
  father[key] = child[key]
91
125
  end
92
126
  end
93
127
  end
94
128
  child.each do |key,value|
95
- father[key] ||= value
129
+ father[key] ||= value if value != "disable"
96
130
  end
97
131
  father
98
132
  end
data/lib/ymlex.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'yaml'
3
3
  require 'logger'
4
+ require 'json'
5
+ require 'optparse'
4
6
 
5
7
  require 'ymlex/ymlex'
8
+ require 'ymlex/argusyml'
metadata CHANGED
@@ -1,23 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ymlex
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Cruel Wen
7
+ - Wen Li
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-14 00:00:00.000000000 Z
11
+ date: 2014-08-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ! 'extend ymal: support inherit and valueize'
14
- email:
15
- executables: []
14
+ email: wenli@baidu.com
15
+ executables:
16
+ - ymlex
16
17
  extensions: []
17
18
  extra_rdoc_files: []
18
19
  files:
19
20
  - lib/ymlex.rb
20
21
  - lib/ymlex/ymlex.rb
22
+ - lib/ymlex/argusyml.rb
23
+ - bin/ymlex
21
24
  homepage: https://github.com/cruelwen/ymlex
22
25
  licenses:
23
26
  - MIT