scaffold_parser 0.5.0 → 0.6.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/Gemfile +2 -0
- data/lib/scaffold_parser.rb +29 -25
- data/lib/scaffold_parser/scaffolders/xsd.rb +140 -33
- data/lib/scaffold_parser/scaffolders/xsd/parser.rb +37 -106
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/all.rb +29 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/at_method.rb +38 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/base_method.rb +36 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/blank.rb +73 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/choice.rb +38 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/class_inherit.rb +17 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/complex_type.rb +46 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/elements.rb +60 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/extension.rb +30 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/import.rb +15 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/include.rb +15 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/klass.rb +121 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/list_method.rb +86 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/module.rb +67 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/module_include.rb +37 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/proxy_list_method.rb +53 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/requires.rb +19 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/sequence.rb +50 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/submodel_method.rb +59 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/handlers/utils.rb +39 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/module_template.rb +35 -0
- data/lib/scaffold_parser/scaffolders/xsd/parser/stack.rb +50 -0
- data/scaffold_parser.gemspec +2 -1
- metadata +39 -6
- data/lib/scaffold_parser/file_patches.rb +0 -13
- data/lib/scaffold_parser/nokogiri_patches.rb +0 -194
- data/lib/scaffold_parser/scaffolders/xsd/builder.rb +0 -105
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a86da6f57bcf43be3e59f2a47531005113ada9ff
|
4
|
+
data.tar.gz: e29b1f9dbea6e921666a001bc51c9213db18e15d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 664fc7cc63285c13ba2b620bc13224f9752a1887ed33c1ac6ee7e20984aecee83b0fdf7b6f21a948b00162e7b47e7931f935f841accb529ed4c8057dcb33480f
|
7
|
+
data.tar.gz: 0d469c89f076255eefad50e3290ab8dc1b59cf11976f7ff25418e1957fda6a1306d3480e355fba259dab6a43b04e255a034d804af9a683b0e18b2376fb1fcba5
|
data/Gemfile
CHANGED
data/lib/scaffold_parser.rb
CHANGED
@@ -1,31 +1,16 @@
|
|
1
|
-
require '
|
1
|
+
require 'xsd_model'
|
2
2
|
require 'active_support/all'
|
3
|
-
require 'scaffold_parser/nokogiri_patches'
|
4
|
-
require 'scaffold_parser/file_patches'
|
5
3
|
require 'scaffold_parser/scaffolders/xsd'
|
6
4
|
|
7
|
-
Nokogiri::XML::Element.include ScaffoldParser::NokogiriPatches::Element
|
8
|
-
Nokogiri::XML::Document.include ScaffoldParser::NokogiriPatches::Document
|
9
|
-
StringIO.include ScaffoldParser::FilePatches
|
10
|
-
|
11
5
|
module ScaffoldParser
|
12
6
|
def self.scaffold(path, options = {})
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
7
|
+
ensure_dir_exists('./tmp/')
|
8
|
+
ensure_dir_exists('./tmp/builders')
|
9
|
+
ensure_dir_exists('./tmp/builders/groups')
|
10
|
+
ensure_dir_exists('./tmp/parsers')
|
11
|
+
ensure_dir_exists('./tmp/parsers/groups')
|
17
12
|
|
18
|
-
|
19
|
-
Dir.mkdir('./tmp/builders')
|
20
|
-
puts './tmp/builders directory created'
|
21
|
-
end
|
22
|
-
|
23
|
-
unless Dir.exists?('./tmp/parsers')
|
24
|
-
Dir.mkdir('./tmp/parsers')
|
25
|
-
puts './tmp/parsers directory created'
|
26
|
-
end
|
27
|
-
|
28
|
-
scaffold_to_string(path, options).each do |path, content|
|
13
|
+
scaffold_to_string(File.read(path), options).each do |path, content|
|
29
14
|
complete_path = path.prepend('./tmp/')
|
30
15
|
|
31
16
|
puts "Writing out #{complete_path}" if options[:verbose]
|
@@ -34,9 +19,28 @@ module ScaffoldParser
|
|
34
19
|
end
|
35
20
|
end
|
36
21
|
|
37
|
-
def self.scaffold_to_string(
|
38
|
-
|
22
|
+
def self.scaffold_to_string(schema, options = {})
|
23
|
+
parse_options = { collect_only: [:element,
|
24
|
+
:complex_type,
|
25
|
+
:sequence,
|
26
|
+
:all,
|
27
|
+
:choice,
|
28
|
+
:schema,
|
29
|
+
:include,
|
30
|
+
:import,
|
31
|
+
:group,
|
32
|
+
:extension] }
|
33
|
+
doc = XsdModel.parse(schema, parse_options)
|
34
|
+
|
35
|
+
Scaffolders::XSD.call(doc, options, parse_options)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
39
|
|
40
|
-
|
40
|
+
def self.ensure_dir_exists(path)
|
41
|
+
unless Dir.exists?(path)
|
42
|
+
Dir.mkdir(path)
|
43
|
+
puts "#{path} directory created"
|
44
|
+
end
|
41
45
|
end
|
42
46
|
end
|
@@ -1,57 +1,59 @@
|
|
1
1
|
require 'scaffold_parser/scaffolders/xsd/parser'
|
2
|
-
require 'scaffold_parser/scaffolders/xsd/
|
2
|
+
require 'scaffold_parser/scaffolders/xsd/parser/handlers/utils'
|
3
3
|
|
4
4
|
module ScaffoldParser
|
5
5
|
module Scaffolders
|
6
6
|
class XSD
|
7
|
-
|
8
|
-
|
7
|
+
include Parser::Handlers::Utils
|
8
|
+
|
9
|
+
def self.call(doc, options, parse_options = {})
|
10
|
+
self.new(doc, options, parse_options).call
|
9
11
|
end
|
10
12
|
|
11
|
-
def initialize(doc, options)
|
13
|
+
def initialize(doc, options, parse_options = {})
|
12
14
|
@doc = doc
|
13
15
|
@options = options
|
16
|
+
@parse_options = parse_options
|
14
17
|
end
|
15
18
|
|
16
19
|
def call
|
17
|
-
|
20
|
+
all = [@doc.schema] + @doc.schema.collect_included_schemas(@parse_options) + @doc.schema.collect_imported_schemas(@parse_options)
|
18
21
|
|
19
|
-
|
22
|
+
classes = Parser.call(all, @options)
|
20
23
|
|
21
|
-
|
24
|
+
classes.each do |klass|
|
25
|
+
klass.methods = klass.methods.map do |meth|
|
26
|
+
if meth.is_a?(Parser::Handlers::SubmodelMethod) && !classes.map(&:name).include?(meth.submodel_class)
|
27
|
+
meth.to_at_method
|
28
|
+
else
|
29
|
+
meth
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
22
33
|
|
23
|
-
|
24
|
-
|
34
|
+
classes.each do |klass|
|
35
|
+
klass.namespace = @options[:namespace]
|
25
36
|
end
|
26
37
|
|
27
|
-
|
28
|
-
|
38
|
+
classes.flat_map do |class_template|
|
39
|
+
[["parsers/#{class_template.name.underscore}.rb", class_template.to_s],
|
40
|
+
["builders/#{class_template.name.underscore}.rb", class_template.to_builder_s],
|
41
|
+
["parsers/base_parser.rb", wrap_in_namespace(base_parser_template, @options[:namespace])],
|
42
|
+
["builders/base_builder.rb", wrap_in_namespace(base_builder_template, @options[:namespace])],
|
43
|
+
["requires.rb", create_requires_template(classes)],
|
44
|
+
["hash_with_attrs.rb", wrap_in_namespace(hash_with_attrs_template, @options[:namespace])],
|
45
|
+
["mega.rb", wrap_in_namespace(mega_template, @options[:namespace])]
|
46
|
+
]
|
47
|
+
end
|
29
48
|
end
|
30
49
|
|
31
50
|
private
|
32
51
|
|
33
|
-
def collect_unscaffolded_subelements(node, collected = [])
|
34
|
-
subelements = node.definition.submodel_nodes.to_a + node.definition.array_nodes.map(&:list_element)
|
35
|
-
.reject(&:xs_type?)
|
36
|
-
.reject { |node| collected.include?(node.to_class_name) }
|
37
|
-
|
38
|
-
subelements.each do |element|
|
39
|
-
if collected.none? { |c| c.to_class_name == element.to_class_name }
|
40
|
-
collected << element
|
41
|
-
|
42
|
-
puts "Collected #{element.to_name} element" if @options[:verbose]
|
43
|
-
|
44
|
-
collect_unscaffolded_subelements(element, collected)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
collected
|
49
|
-
end
|
50
|
-
|
51
52
|
def base_parser_template
|
52
53
|
<<~TEMPLATE
|
53
54
|
module Parsers
|
54
55
|
module BaseParser
|
56
|
+
include Mega
|
55
57
|
EMPTY_ARRAY = []
|
56
58
|
|
57
59
|
attr_accessor :raw
|
@@ -95,6 +97,12 @@ module ScaffoldParser
|
|
95
97
|
klass.new(element)
|
96
98
|
end
|
97
99
|
end
|
100
|
+
|
101
|
+
def to_h_with_attrs
|
102
|
+
hash = HashWithAttributes.new({}, attributes)
|
103
|
+
|
104
|
+
hash
|
105
|
+
end
|
98
106
|
end
|
99
107
|
end
|
100
108
|
TEMPLATE
|
@@ -104,18 +112,25 @@ module ScaffoldParser
|
|
104
112
|
<<~TEMPLATE
|
105
113
|
module Builders
|
106
114
|
module BaseBuilder
|
107
|
-
attr_accessor :name, :data
|
115
|
+
attr_accessor :name, :data, :options
|
108
116
|
|
109
|
-
def initialize(name, data = {})
|
117
|
+
def initialize(name, data = {}, options = {})
|
110
118
|
@name = name
|
111
119
|
@data = data || {}
|
120
|
+
@options = options || {}
|
112
121
|
end
|
113
122
|
|
114
123
|
def to_xml
|
115
|
-
|
124
|
+
encoding = options[:encoding]
|
125
|
+
|
126
|
+
doc_options = { version: '1.0' }
|
127
|
+
doc_options[:encoding] = encoding if encoding
|
128
|
+
doc = Ox::Document.new(doc_options)
|
116
129
|
doc << builder
|
117
130
|
|
118
|
-
|
131
|
+
dump_options = { with_xml: true }
|
132
|
+
dump_options[:encoding] = encoding if encoding
|
133
|
+
Ox.dump(doc, dump_options)
|
119
134
|
end
|
120
135
|
|
121
136
|
def build_element(name, content)
|
@@ -135,6 +150,98 @@ module ScaffoldParser
|
|
135
150
|
end
|
136
151
|
TEMPLATE
|
137
152
|
end
|
153
|
+
|
154
|
+
def hash_with_attrs_template
|
155
|
+
<<~TEMPLATE
|
156
|
+
class HashWithAttributes
|
157
|
+
def initialize(hash, attributes = nil)
|
158
|
+
@hash = hash
|
159
|
+
@attributes = attributes if attributes
|
160
|
+
end
|
161
|
+
|
162
|
+
def value
|
163
|
+
@hash
|
164
|
+
end
|
165
|
+
|
166
|
+
def attributes
|
167
|
+
@attributes ||= {}
|
168
|
+
end
|
169
|
+
|
170
|
+
def attributes=(attributes)
|
171
|
+
@attributes = attributes
|
172
|
+
end
|
173
|
+
|
174
|
+
def ==(other)
|
175
|
+
if other.respond_to?(:value) && other.respond_to?(:attributes)
|
176
|
+
value == other.value && other.attributes == attributes
|
177
|
+
else
|
178
|
+
value == other
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def merge(other)
|
183
|
+
merged_hash = value.merge other.value
|
184
|
+
merged_attrs = attributes.merge other.attributes
|
185
|
+
|
186
|
+
self.class.new(merged_hash, merged_attrs)
|
187
|
+
end
|
188
|
+
|
189
|
+
def key?(key)
|
190
|
+
value.key? key
|
191
|
+
end
|
192
|
+
|
193
|
+
def [](key)
|
194
|
+
value[key]
|
195
|
+
end
|
196
|
+
|
197
|
+
def []=(key, key_value)
|
198
|
+
value[key] = key_value
|
199
|
+
end
|
200
|
+
|
201
|
+
def dig(*attrs)
|
202
|
+
value.dig(*attrs)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
TEMPLATE
|
206
|
+
end
|
207
|
+
|
208
|
+
def mega_template
|
209
|
+
<<~TEMPLATE
|
210
|
+
module Mega
|
211
|
+
def mega
|
212
|
+
called_from = caller_locations[0].label
|
213
|
+
included_modules = (self.class.included_modules - Class.included_modules - [Mega])
|
214
|
+
included_modules.map { |m| m.instance_method(called_from).bind(self).call }
|
215
|
+
end
|
216
|
+
end
|
217
|
+
TEMPLATE
|
218
|
+
end
|
219
|
+
|
220
|
+
def create_requires_template(classes)
|
221
|
+
modules = classes.select { |cl| cl.is_a? Parser::Handlers::Module }
|
222
|
+
classes = classes.select { |cl| cl.is_a? Parser::Handlers::Klass }
|
223
|
+
with_inheritance, others = classes.partition { |klass| klass.inherit_from }
|
224
|
+
|
225
|
+
requires = ['parsers/base_parser', 'builders/base_builder']
|
226
|
+
modules.each do |klass|
|
227
|
+
requires << "parsers/#{klass.name.underscore}"
|
228
|
+
requires << "builders/#{klass.name.underscore}"
|
229
|
+
end
|
230
|
+
others.each do |klass|
|
231
|
+
requires << "parsers/#{klass.name.underscore}"
|
232
|
+
requires << "builders/#{klass.name.underscore}"
|
233
|
+
end
|
234
|
+
with_inheritance.each do |klass|
|
235
|
+
requires << "parsers/#{klass.name.underscore}"
|
236
|
+
requires << "builders/#{klass.name.underscore}"
|
237
|
+
end
|
238
|
+
|
239
|
+
if @options[:namespace]
|
240
|
+
requires = requires.map { |r| r.prepend("#{@options[:namespace].underscore}/") }
|
241
|
+
end
|
242
|
+
|
243
|
+
requires.map { |r| "require '#{r}'" }.join("\n")
|
244
|
+
end
|
138
245
|
end
|
139
246
|
end
|
140
247
|
end
|
@@ -1,122 +1,53 @@
|
|
1
|
+
require 'scaffold_parser/scaffolders/xsd/parser/stack'
|
2
|
+
require 'scaffold_parser/scaffolders/xsd/parser/handlers/requires'
|
3
|
+
|
1
4
|
module ScaffoldParser
|
2
5
|
module Scaffolders
|
3
6
|
class XSD
|
4
7
|
class Parser
|
5
|
-
attr_reader :
|
8
|
+
attr_reader :xsds
|
6
9
|
|
7
|
-
def self.call(
|
8
|
-
self.new(
|
10
|
+
def self.call(xsds, options)
|
11
|
+
self.new(xsds, options).call
|
9
12
|
end
|
10
13
|
|
11
|
-
def initialize(
|
12
|
-
@
|
14
|
+
def initialize(xsds, options)
|
15
|
+
@xsds = xsds
|
13
16
|
@options = options
|
14
17
|
end
|
15
18
|
|
16
|
-
|
17
|
-
puts "Scaffolding parser for #{node.to_name}" if @options[:verbose]
|
18
|
-
|
19
|
-
f = StringIO.new
|
20
|
-
f.indent = true if @options[:namespace]
|
21
|
-
|
22
|
-
f.puts "require '#{namespaced('parsers/base_parser')}'"
|
23
|
-
node.submodel_nodes.map { |n| namespaced(n.to_class_name.underscore.prepend('parsers/')) }.uniq.each { |n| f.puts "require '#{n}'" }
|
24
|
-
node.array_nodes.reject { |l| l.list_element.xs_type? }.each { |n| f.puts "require '#{namespaced(n.list_element.to_class_name.underscore.prepend('parsers/'))}'" }
|
25
|
-
f.puts
|
26
|
-
|
27
|
-
f.puts "module #{@options[:namespace]}" if @options[:namespace]
|
28
|
-
f.putsi "module Parsers"
|
29
|
-
f.putsi " class #{node.to_class_name}"
|
30
|
-
f.putsi " include BaseParser"
|
31
|
-
|
32
|
-
node.value_nodes.each do |method|
|
33
|
-
f.puts
|
34
|
-
|
35
|
-
method_name = method.to_name.underscore
|
36
|
-
at = method.to_name
|
37
|
-
|
38
|
-
f.putsi " def #{method_name}"
|
39
|
-
f.putsi " at '#{at}'"
|
40
|
-
f.putsi " end"
|
41
|
-
end
|
42
|
-
|
43
|
-
node.submodel_nodes.each do |method|
|
44
|
-
f.puts
|
45
|
-
|
46
|
-
klass = method.to_class_name
|
47
|
-
method_name = method.to_name.underscore
|
48
|
-
at = method.to_name
|
49
|
-
|
50
|
-
f.putsi " def #{method_name}"
|
51
|
-
f.putsi " submodel_at(#{klass}, '#{at}')"
|
52
|
-
f.putsi " end"
|
53
|
-
end
|
54
|
-
|
55
|
-
node.array_nodes.reject { |l| l.list_element.xs_type? }.each do |method|
|
56
|
-
f.puts
|
57
|
-
|
58
|
-
list_element_klass = method.list_element_klass
|
59
|
-
method_name = method.to_name.underscore
|
60
|
-
list_element_at = method.list_element_at.map { |e| "'#{e}'" }.join(', ')
|
19
|
+
STACK = Stack.instance
|
61
20
|
|
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
|
-
lines << "hash[:#{node.to_name.underscore}] = #{node.to_name.underscore}.map(&:to_h_with_attrs) if has? '#{node.to_name}'"
|
90
|
-
end
|
91
|
-
node.array_nodes.select { |l| l.list_element.xs_type? }.each do |node|
|
92
|
-
lines << "hash[:#{node.to_name.underscore}] = #{node.to_name.underscore} if has? '#{node.to_name}'"
|
93
|
-
end
|
94
|
-
if lines.any?
|
95
|
-
f.puts
|
96
|
-
|
97
|
-
f.putsi " def to_h_with_attrs"
|
98
|
-
f.putsi " hash = HashWithAttributes.new({}, attributes)"
|
99
|
-
f.puts
|
100
|
-
|
101
|
-
lines.each do |line|
|
102
|
-
f.putsi " #{line}"
|
21
|
+
def call
|
22
|
+
STACK.clear
|
23
|
+
|
24
|
+
classes =
|
25
|
+
xsds.map do |xsd|
|
26
|
+
if @options[:verbose]
|
27
|
+
puts "\n\nScaffolding schema which defines:\n#{xsd.children.map { |c| c.name }.compact}\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
xsd.reverse_traverse do |element, children_result|
|
31
|
+
handler =
|
32
|
+
if children_result.empty?
|
33
|
+
Handlers::Blank.new
|
34
|
+
elsif children_result.one?
|
35
|
+
children_result.first
|
36
|
+
else
|
37
|
+
Handlers::Elements.new(children_result)
|
38
|
+
end
|
39
|
+
|
40
|
+
if @options[:verbose]
|
41
|
+
current_handler = handler.class.to_s.demodulize
|
42
|
+
childrens = (handler.instance_variable_get('@elements') || []).map { |child| child.class.to_s.demodulize }
|
43
|
+
puts "#{current_handler}#{childrens}##{element.element_name}"
|
44
|
+
end
|
45
|
+
|
46
|
+
handler.send(element.element_name, element)
|
47
|
+
end
|
103
48
|
end
|
104
|
-
f.puts
|
105
|
-
|
106
|
-
f.putsi " hash"
|
107
|
-
f.putsi " end"
|
108
|
-
end
|
109
|
-
f.putsi " end"
|
110
|
-
f.putsi "end"
|
111
|
-
f.puts "end" if @options[:namespace]
|
112
|
-
|
113
|
-
["parsers/#{node.to_class_name.underscore}.rb", f.string.strip]
|
114
|
-
end
|
115
|
-
|
116
|
-
private
|
117
49
|
|
118
|
-
|
119
|
-
[@options[:namespace]&.underscore, path].compact.join('/')
|
50
|
+
classes = STACK.to_a
|
120
51
|
end
|
121
52
|
end
|
122
53
|
end
|