kwalify 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  ##
2
2
  ## Kwalify schema example for address book
3
3
  ##
4
- ## $Release: 0.4.1 $
4
+ ## $Release: 0.5.0 $
5
5
  ## copyright(c) 2005 kuwata-lab all rights reserved.
6
6
  ##
7
7
  ##
@@ -1,8 +1,8 @@
1
1
  ###
2
2
  ### Kwalify schema example for invoice
3
3
  ###
4
- ### $Rev: 20 $
5
- ### $Release: 0.4.1 $
4
+ ### $Rev: 41 $
5
+ ### $Release: 0.5.0 $
6
6
  ### copyright(c) 2005 kuwata-lab all rights reserved.
7
7
  ###
8
8
 
@@ -1,7 +1,7 @@
1
1
  ##
2
2
  ## Kwalify schema example for TapKit
3
3
  ##
4
- ## $Release: 0.4.1 $
4
+ ## $Release: 0.5.0 $
5
5
  ## copyright(c) 2005 kuwata-lab all rights reserved.
6
6
  ##
7
7
 
@@ -62,44 +62,44 @@ mapping:
62
62
  sequence:
63
63
  - type: map
64
64
  mapping:
65
- "name":
66
- type: str
67
- required: yes
68
- unique: yes
69
- "column_name":
70
- type: text
71
- required: yes
72
- "class_name":
73
- type: str
74
- enum:
75
- - String
76
- - Integer
77
- - Float
78
- - Date
79
- - Time
80
- - Timestamp
81
- - Boolean
82
- "external_type":
83
- type: str
84
- required: yes
85
- enum: [
86
- char, character, varchar, char varying, character varying,
87
- nchar, national char, national character,
88
- national character varying, bit, bit varying,
89
- int, integer, smallint, interval,
90
- numeric, decimal, dec, float, real, double presicion,
91
- date, time, timestamp
92
- ]
93
- "allow_null":
94
- type: bool
95
- "read_only":
96
- type: bool
97
- "width":
98
- type: int
99
- "factory_method":
100
- type: str
101
- "convertion_method":
102
- type: str
65
+ "name":
66
+ type: str
67
+ required: yes
68
+ unique: yes
69
+ "column_name":
70
+ type: str
71
+ required: yes
72
+ "class_name":
73
+ type: str
74
+ enum:
75
+ - String
76
+ - Integer
77
+ - Float
78
+ - Date
79
+ - Time
80
+ - Timestamp
81
+ - Boolean
82
+ "external_type":
83
+ type: str
84
+ required: yes
85
+ enum: [
86
+ char, character, varchar, char varying, character varying,
87
+ nchar, national char, national character,
88
+ national character varying, bit, bit varying,
89
+ int, integer, smallint, interval,
90
+ numeric, decimal, dec, float, real, double presicion,
91
+ date, time, timestamp
92
+ ]
93
+ "allow_null":
94
+ type: bool
95
+ "read_only":
96
+ type: bool
97
+ "width":
98
+ type: int
99
+ "factory_method":
100
+ type: str
101
+ "convertion_method":
102
+ type: str
103
103
  "relationships":
104
104
  type: seq
105
105
  sequence:
@@ -1,13 +1,13 @@
1
1
  ###
2
- ### $Rev: 26 $
3
- ### $Release: 0.4.1 $
2
+ ### $Rev: 42 $
3
+ ### $Release: 0.5.0 $
4
4
  ### copyright(c) 2005 kuwata-lab all rights reserved.
5
5
  ###
6
6
 
7
7
 
8
8
  module Kwalify
9
9
 
10
- RELEASE = ("$Release: 0.4.1 $" =~ /[.\d]+/) && $&
10
+ RELEASE = ("$Release: 0.5.0 $" =~ /[.\d]+/) && $&
11
11
 
12
12
  end
13
13
 
@@ -17,4 +17,4 @@ require 'kwalify/errors'
17
17
  require 'kwalify/rule'
18
18
  require 'kwalify/validator'
19
19
  require 'kwalify/meta-validator'
20
- require 'kwalify/parser'
20
+ require 'kwalify/yaml-parser'
@@ -1,6 +1,6 @@
1
1
  ###
2
- ### $Rev: 27 $
3
- ### $Release: 0.4.1 $
2
+ ### $Rev: 42 $
3
+ ### $Release: 0.5.0 $
4
4
  ### copyright(c) 2005 kuwata-lab all rights reserved.
5
5
  ###
6
6
 
@@ -22,10 +22,10 @@ module Kwalify
22
22
  class BaseError < KwalifyError
23
23
  def initialize(message="", path=nil, value=nil, rule=nil, error_symbol=nil)
24
24
  super(message)
25
- @error_symbol = error_symbol
25
+ @path = path
26
26
  @rule = rule
27
- @path = path
28
27
  @value = value
28
+ @error_symbol = error_symbol
29
29
  end
30
30
  attr_reader :error_symbol, :rule, :path, :value
31
31
  attr_accessor :linenum
@@ -43,6 +43,10 @@ module Kwalify
43
43
  def to_s
44
44
  return "[#{path()}] #{message()}"
45
45
  end
46
+
47
+ def <=>(ex)
48
+ return @linenum <=> ex.linenum
49
+ end
46
50
  end
47
51
 
48
52
 
@@ -60,12 +64,13 @@ module Kwalify
60
64
  end
61
65
 
62
66
 
63
- class ParseError < KwalifyError
64
- def initialize(msg, linenum)
67
+ class YamlSyntaxError < KwalifyError
68
+ def initialize(msg, linenum, error_symbol)
65
69
  super("line #{linenum}: #{msg}")
66
70
  @linenum = linenum
71
+ @error_symbol
67
72
  end
68
- attr_accessor :linenum
73
+ attr_accessor :linenum, :error_symbol
69
74
  end
70
75
 
71
76
 
@@ -76,19 +81,21 @@ module Kwalify
76
81
  end
77
82
 
78
83
  def validate_error(error_symbol, rule, path, val, args=nil)
79
- return _create_error(ValidationError, error_symbol, rule, path, val, args)
84
+ msg = _build_message(error_symbol, val, args);
85
+ return ValidationError.new(msg, path, val, rule, error_symbol)
80
86
  end
81
87
 
82
88
  def schema_error(error_symbol, rule, path, val, args=nil)
83
- return _create_error(SchemaError, error_symbol, rule, path, val, args)
89
+ msg = _build_message(error_symbol, val, args);
90
+ return SchemaError.new(msg, path, val, rule, error_symbol)
84
91
  end
85
92
 
86
- def _create_error(error_klass, error_symbol, rule, path, val, args)
87
- msg = Kwalify.msg(error_symbol)
88
- assert_error("error_symbol=#{error_symbol.inspect}") unless msg
93
+ def _build_message(message_key, val, args)
94
+ msg = Kwalify.msg(message_key)
95
+ assert_error("message_key=#{message_key.inspect}") unless msg
89
96
  msg = msg % args if args
90
- msg = "'#{val.to_s.gsub(/\n/, '\n')}': #{msg}" if val != nil && Kwalify.scalar?(val)
91
- return error_klass.new(msg, path, val, rule, error_symbol)
97
+ msg = "'#{val.to_s.gsub(/\n/, '\n')}': #{msg}" if val != nil && Types.scalar?(val)
98
+ return msg;
92
99
  end
93
100
 
94
101
  end
@@ -0,0 +1,357 @@
1
+ ###
2
+ ### $Rev: 42 $
3
+ ### $Release: 0.5.0 $
4
+ ### copyright(c) 2005 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ require 'yaml'
8
+ require 'kwalify'
9
+ require 'kwalify/util/yaml-helper'
10
+ #require 'kwalify/util/option-parser'
11
+
12
+
13
+ module Kwalify
14
+
15
+ class CommandOptionError < KwalifyError
16
+ def initialize(message, option, error_symbol)
17
+ super(message)
18
+ @option = option
19
+ @error_symbol = error_symbol
20
+ end
21
+ attr_reader :option, :error_symbol
22
+ end
23
+
24
+
25
+ ##
26
+ ## ex.
27
+ ## command = File.basename($0)
28
+ ## begin
29
+ ## main = Kwalify::Main.new(command)
30
+ ## s = main.execute
31
+ ## print s if s
32
+ ## rescue Kwalify::CommandOptionError => ex
33
+ ## $stderr.puts "ERROR: #{ex.message}"
34
+ ## exit 1
35
+ ## rescue Kwalify::KwalifyError => ex
36
+ ## $stderr.puts "ERROR: #{ex.message}"
37
+ ## exit 1
38
+ ## end
39
+ ##
40
+ class Main
41
+
42
+ def initialize(command=nil)
43
+ @command = command || File.basename($0)
44
+ @flag_help = false
45
+ @flag_version = false
46
+ @flag_silent = false
47
+ @flag_meta = false
48
+ @flag_untabify = false
49
+ @flag_linenum = false
50
+ @flag_debug = false
51
+ @schema_filename = nil
52
+ @properties = {}
53
+ end
54
+
55
+ def _inspect()
56
+ s = ""
57
+ s << "command : #{@command}\n"
58
+ s << "flag_help : #{@flag_help}\n"
59
+ s << "flag_version : #{@flag_version}\n"
60
+ s << "flag_silent : #{@flag_silent}\n"
61
+ s << "flag_meta : #{@flag_meta}\n"
62
+ s << "flag_untabify : #{@flag_untabify}\n"
63
+ s << "flag_linenum : #{@flag_linenum}\n"
64
+ s << "flag_debug : #{@flag_debug}\n"
65
+ s << "schema_filename : #{@schema_filename != nil ? @schema_filename : 'null'}\n"
66
+ s << "properties:\n"
67
+ @properties.each do |key, val|
68
+ s << " #{key}: #{val}\n"
69
+ end
70
+ return s
71
+ end
72
+
73
+
74
+ def execute(argv=ARGV)
75
+ filenames = _parse_argv(argv)
76
+
77
+ s = ''
78
+ s << _version() << "\n" if @flag_version
79
+ s << _usage() if @flag_help
80
+ return s unless s.empty?
81
+
82
+ if @flag_meta || @flag_meta2
83
+ s = _meta_validate(filenames)
84
+ elsif @schema_filename
85
+ if @flag_debug
86
+ s = _inspect_schema(@flag_schema)
87
+ else
88
+ s = _validate(filenames)
89
+ end
90
+ else
91
+ #* key=:command_option_noaction msg="command-line option '-f' or '-m' required."
92
+ raise option_error(:command_option_noaction, @command)
93
+ end
94
+ return s # or return (s == nil || s.empty?) ? nil : s
95
+ end
96
+
97
+
98
+ def self.main(command, argv=ARGV)
99
+ begin
100
+ main = Kwalify::Main.new(command)
101
+ s = main.execute(ARGV)
102
+ print s if s
103
+ #rescue Kwalify::CommandOptionError => ex
104
+ # $stderr.puts ex.message
105
+ # exit 1
106
+ #rescue Kwalify::KwalifyError => ex
107
+ # $stderr.puts "ERROR: #{ex.message}"
108
+ # exit 1
109
+ rescue => ex
110
+ $stderr.puts ex.message
111
+ exit 1
112
+ end
113
+ end
114
+
115
+
116
+ private
117
+
118
+
119
+ def option_error(error_symbol, arg)
120
+ msg = Kwalify.msg(error_symbol) % arg
121
+ return CommandOptionError.new(msg, arg, error_symbol)
122
+ end
123
+
124
+
125
+ def _load_yaml(str)
126
+ str = YamlHelper.untabify(str) if @flag_untabify
127
+ if @flag_linenum
128
+ @parser = Kwalify::YamlParser.new(str)
129
+ doc = @parser.parse()
130
+ else
131
+ doc = YAML.load(str)
132
+ doc = doc.value if _domain_type?(doc)
133
+ end
134
+ return doc
135
+ end
136
+
137
+
138
+ def _meta_validate(filenames)
139
+ filenames = [ nil ] if filenames.empty?
140
+ meta_validator = @flag_meta2 ? nil : Kwalify::MetaValidator.instance()
141
+ flag_no_validate = @flag_meta2 == true
142
+ s = ''
143
+ filenames.each do |filename|
144
+ s << __meta_validate(meta_validator, filename)
145
+ end
146
+ return s
147
+ end
148
+
149
+
150
+ def __meta_validate(meta_validator, filename=nil)
151
+ str = filename ? File.open(filename) { |f| f.read() } : $stdin.read()
152
+ schema = _load_yaml(str)
153
+ filename ||= "(stdin)"
154
+ if !schema || schema.empty?
155
+ #* key=:meta_empty msg="%s: empty.\n"
156
+ return Kwalify.msg(:meta_emtpy) % filename
157
+ end
158
+ errors = nil
159
+ if meta_validator
160
+ errors = meta_validator.validate(schema)
161
+ else
162
+ begin
163
+ validator = Kwalify::Validator.new(schema) # error raised when schema is wrong
164
+ rescue Kwalify::SchemaError => ex
165
+ errors = [ ex ]
166
+ end
167
+ end
168
+ s = ''
169
+ if !errors || errors.empty?
170
+ #* key=:meta_valid msg="%s: ok.\n"
171
+ s << (Kwalify.msg(:meta_valid) % filename) unless @flag_silent
172
+ else
173
+ #* key=:meta_invalid msg="%s: NG!\n"
174
+ s << (Kwalify.msg(:meta_invalid) % filename)
175
+ s << _errors_to_str(errors)
176
+ end
177
+ return s
178
+ end
179
+
180
+
181
+ def _errors_to_str(errors)
182
+ s = ''
183
+ flag_linenum = @flag_linenum
184
+ if flag_linenum
185
+ @parser.set_errors_linenum(errors)
186
+ errors = errors.sort
187
+ end
188
+ errors.each do |error|
189
+ if flag_linenum
190
+ s << " - (line #{error.linenum}) [#{error.path}] #{error.message}\n"
191
+ else
192
+ s << " - [#{error.path}] #{error.message}\n"
193
+ end
194
+ end
195
+ return s
196
+ end
197
+
198
+
199
+ def _validate(filenames)
200
+ str = File.open(@schema_filename) { |f| f.read() }
201
+ schema = _load_yaml(str)
202
+ validator = Kwalify::Validator.new(schema)
203
+ #
204
+ filenames = [ nil ] if filenames.empty?
205
+ s = ''
206
+ filenames.each do |filename|
207
+ s << __validate(validator, filename)
208
+ end
209
+ return s
210
+ end
211
+
212
+
213
+ def __validate(validator, filename=nil)
214
+ str = filename ? File.open(filename) { |f| f.read() } : $stdin.read()
215
+ filename ||= "(stdin)"
216
+ s = ''
217
+ i = -1
218
+ _each_yaml_documents(str) do |document|
219
+ i += 1
220
+ if !document || document.empty?
221
+ #* key=:schema_empty msg="%s#%d: empty.\n"
222
+ s << (Kwalify.msg(:schema_empty) % i)
223
+ next
224
+ end
225
+ errors = validator.validate(document)
226
+ if errors.empty?
227
+ #* key=:validation_valid msg="%s#%d: valid.\n"
228
+ s << (Kwalify.msg(:validation_valid) % [filename, i]) unless @flag_silent
229
+ else
230
+ #* key=:validation_invalid msg="%s#%d: INVALID\n"
231
+ s << (Kwalify.msg(:validation_invalid) % [filename, i])
232
+ s << _errors_to_str(errors)
233
+ end
234
+ end
235
+ return s
236
+ end
237
+
238
+
239
+ def _each_yaml_documents(str, &block)
240
+ str = YamlHelper.untabify(str) if @flag_untabify
241
+ if @flag_linenum
242
+ @parser = Kwalify::YamlParser.new(str)
243
+ while @parser.has_next()
244
+ doc = @parser.parse()
245
+ yield(doc)
246
+ end
247
+ else
248
+ YAML::load_documents(str) do |doc|
249
+ doc = doc.value if _domain_type?(doc)
250
+ yield(doc)
251
+ end
252
+ end
253
+ end
254
+
255
+
256
+ def _inspect_schema(schema_filename)
257
+ filename = schema_filename
258
+ str = filename ? File.open(filename) { |f| f.read() } : $stdin.read()
259
+ schema = _load_yaml(str)
260
+ return nil if !schema || schema.empty?
261
+ validator = Kwalify::Validator.new(schema) # error raised when schema is wrong
262
+ s = validator._inspect()
263
+ s << "\n" unless s[-1] == ?\n
264
+ return s
265
+ end
266
+
267
+
268
+ def _usage()
269
+ s = ''
270
+ s << "Usage1: #{@command} [-hvstl] -f schema.yaml document.yaml [document2.yaml ...]\n"
271
+ s << "Usage2: #{@command} [-hvstl] -m schema.yaml [schema2.yaml ...]\n"
272
+ s << " -h, --help : help\n"
273
+ s << " -v : version\n"
274
+ s << " -s : silent\n"
275
+ s << " -f schema.yaml : schema definition file\n"
276
+ s << " -m : meta-validation mode\n"
277
+ s << " -t : expand tab character automatically\n"
278
+ s << " -l : show linenumber when errored (experimental)\n"
279
+ return s
280
+ end
281
+
282
+
283
+ def _version()
284
+ return RELEASE
285
+ end
286
+
287
+ def _to_value(str)
288
+ case str
289
+ when nil, "null", "nil" ; return nil
290
+ when "true", "yes" ; return true
291
+ when "false", "no" ; return false
292
+ when /\A\d+\z/ ; return str.to_i
293
+ when /\A\d+\.\d+\z/ ; return str.to_f
294
+ when /\/(.*)\// ; return Regexp.new($1)
295
+ when /\A'.*'\z/, /\A".*"\z/ ; return eval(str)
296
+ else ; return str
297
+ end
298
+ end
299
+
300
+ def _parse_argv(argv)
301
+ while argv[0] && argv[0][0] == ?-
302
+ optstr = argv.shift
303
+ optstr = optstr[1, optstr.length-1]
304
+ # property
305
+ if optstr[0] == ?-
306
+ unless optstr =~ /\A\-([-\w]+)(?:=(.*))?\z/
307
+ #* key=:command_property_invalid msg="%s: invalid property."
308
+ raise option_error(:command_property_invalid, optstr)
309
+ end
310
+ prop_name = $1; prop_value = $2
311
+ key = prop_name.gsub(/-/, '_').intern
312
+ value = prop_value == nil ? true : _to_value(prop_value)
313
+ @properties[key] = value
314
+ # option
315
+ else
316
+ while optstr && !optstr.empty?
317
+ optchar = optstr[0]
318
+ optstr[0,1] = ""
319
+ case optchar
320
+ when ?h ; @flag_help = true
321
+ when ?v ; @flag_version = true
322
+ when ?s ; @flag_silent = true
323
+ when ?t ; @flag_untabify = true
324
+ when ?l ; @flag_linenum = true
325
+ when ?m ; @flag_meta = true
326
+ when ?M ; @flag_meta2 = true
327
+ when ?D ; @flag_debug = true
328
+ when ?f ;
329
+ arg = optstr.empty? ? argv.shift : optstr
330
+ #* key=:command_option_noarg msg="-%s: argument required."
331
+ #* key=:command_option_noschema msg="-%s: schema filename required."
332
+ raise option_error(:command_option_noschema, "f") unless arg
333
+ @schema_filename = arg
334
+ optstr = nil
335
+ else
336
+ #* key=:command_option_invalid msg="-%s: invalid command option."
337
+ raise option_error(:command_option_invalid, optchar.chr)
338
+ end
339
+ end
340
+ end
341
+ end # end of while
342
+ #
343
+ @flag_help = true if @properties[:help]
344
+ @flag_version = true if @properties[:version]
345
+ filenames = argv
346
+ return filenames
347
+ end
348
+
349
+
350
+ def _domain_type?(doc)
351
+ klass = defined?(YAML::DomainType) ? YAML::DomainType : YAML::Syck::DomainType
352
+ return doc.is_a?(klass)
353
+ end
354
+
355
+ end
356
+
357
+ end