kwalify 0.4.1 → 0.5.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.
@@ -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