lacerda 1.0.0.beta1 → 1.0.0.beta2
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/CHANGELOG.markdown +6 -0
- data/lacerda.gemspec +1 -1
- data/lib/lacerda/conversion.rb +71 -22
- data/lib/lacerda/conversion/data_structure.rb +22 -19
- data/lib/lacerda/version.rb +1 -1
- metadata +21 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e35159525996db21a172b54b47eb0d5f9c1e8c4f
|
4
|
+
data.tar.gz: 79cf8de3685ca9632dd67ec61f8e2e5720f0beb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fa08291be1572c8524b8d7d0c1995335ede5199821ed25eb56584a4c2381c6a996c55cfb9ea446bb0671d8628c32bb145ed0fafe73b76fcf69d0ab79c6e1a21
|
7
|
+
data.tar.gz: 1278693d32b1e496f5c361a5c27306a85af33559f6aefb3daf1e9c7e6f5ce878cad62eb6d01c19f611bac741ff174bd5635a2426193087476b17a6302d3d4761
|
data/CHANGELOG.markdown
CHANGED
data/lacerda.gemspec
CHANGED
@@ -24,9 +24,9 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.add_runtime_dependency "json-schema", ["~> 2.6.2"]
|
26
26
|
|
27
|
-
spec.add_runtime_dependency "redsnow", ["~> 0.4.3"]
|
28
27
|
spec.add_runtime_dependency "colorize"
|
29
28
|
spec.add_runtime_dependency "blumquist", ["~> 0.5"]
|
29
|
+
spec.add_runtime_dependency "lounge_lizard", [">= 0.1.3", "~> 0.1"]
|
30
30
|
|
31
31
|
spec.add_runtime_dependency "tins"
|
32
32
|
|
data/lib/lacerda/conversion.rb
CHANGED
@@ -2,8 +2,8 @@ require 'fileutils'
|
|
2
2
|
require 'open3'
|
3
3
|
require 'lacerda/conversion/apiary_to_json_schema'
|
4
4
|
require 'lacerda/conversion/error'
|
5
|
-
require 'redsnow'
|
6
5
|
require 'colorize'
|
6
|
+
require 'lounge_lizard'
|
7
7
|
|
8
8
|
module Lacerda
|
9
9
|
module Conversion
|
@@ -31,10 +31,11 @@ module Lacerda
|
|
31
31
|
# Parse MSON to an apiary blueprint AST
|
32
32
|
# (see https://github.com/apiaryio/api-blueprint)
|
33
33
|
ast_file = mson_to_ast_json(filename)
|
34
|
+
raise_parsing_errors(filename, ast_file)
|
34
35
|
|
35
36
|
# Pluck out Data structures from it
|
36
37
|
data_structures = data_structures_from_blueprint_ast(ast_file)
|
37
|
-
|
38
|
+
|
38
39
|
# Generate json schema from each contained data structure
|
39
40
|
schema = {
|
40
41
|
"$schema" => "http://json-schema.org/draft-04/schema#",
|
@@ -81,8 +82,8 @@ module Lacerda
|
|
81
82
|
# }
|
82
83
|
#
|
83
84
|
data_structures.each do |data|
|
84
|
-
id = data['
|
85
|
-
json= DataStructure.new(id, data, nil).to_json
|
85
|
+
id = data['content'].first['meta']['id']
|
86
|
+
json= DataStructure.new(id, data['content'], nil).to_json
|
86
87
|
member = json.delete('title')
|
87
88
|
schema['definitions'][member] = json
|
88
89
|
schema['properties'][member] = {"$ref" => "#/definitions/#{member}"}
|
@@ -97,10 +98,56 @@ module Lacerda
|
|
97
98
|
true
|
98
99
|
end
|
99
100
|
|
101
|
+
def self.raise_parsing_errors(mson_file, ast_file)
|
102
|
+
parsing_errors = ast_parsing_errors(ast_file)
|
103
|
+
return if parsing_errors.empty?
|
104
|
+
raise Error, parsing_errors.prepend("The following errors were found in #{mson_file}:").join("\n")
|
105
|
+
end
|
106
|
+
|
107
|
+
# The structure is of an AST is normally something like
|
108
|
+
# parseResult
|
109
|
+
# - category # (meta => api) It seems there is always only 1
|
110
|
+
# - category # (meta => dataStructures) It seems there is always only 1
|
111
|
+
# - dataStructure # Bunch of data structures
|
112
|
+
# . . .
|
113
|
+
# - dataStructure
|
114
|
+
# . . .
|
115
|
+
#
|
116
|
+
# - annotation # Bunch of annotations(errors/warnings
|
117
|
+
# . . .
|
118
|
+
# - annotation
|
119
|
+
# . . .
|
100
120
|
def self.data_structures_from_blueprint_ast(filename)
|
101
|
-
|
102
|
-
|
103
|
-
|
121
|
+
# The content of the ast parsing
|
122
|
+
elements = parse_result_contents_from_ast_file(filename)
|
123
|
+
|
124
|
+
# We keep the content of the categories only, they could be annotations otherwise
|
125
|
+
result_categories = elements.select do |element|
|
126
|
+
element['element'] == 'category'
|
127
|
+
end.map { |category| category['content'] }.flatten
|
128
|
+
|
129
|
+
# From these categories we keep the 'dataStructures' category contents.
|
130
|
+
# If there could be other types, no idea ¯\_(ツ)_/¯
|
131
|
+
data_structures_categories_contents = result_categories.select do |result_category|
|
132
|
+
result_category['meta']['classes'].include?('dataStructures')
|
133
|
+
end.map { |data_structures_category| data_structures_category['content'] }.flatten
|
134
|
+
|
135
|
+
# From the contents of 'dataStructures' categories we keep
|
136
|
+
# the 'dataStructure' elements. If there could be other types,
|
137
|
+
# no idea ¯\_(ツ)_/¯
|
138
|
+
data_structures_categories_contents.select do |data_structures_content|
|
139
|
+
data_structures_content['element'] == 'dataStructure'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.ast_parsing_annotation_messages(filename, type)
|
144
|
+
annotations = annotations_from_blueprint_ast(filename).select do |annotation|
|
145
|
+
annotation['meta']['classes'].include?(type)
|
146
|
+
end
|
147
|
+
return [] if annotations.empty?
|
148
|
+
annotations.map do |annotation|
|
149
|
+
"#{type.capitalize} code #{annotation['attributes']['code']}: #{annotation['content']}"
|
150
|
+
end
|
104
151
|
end
|
105
152
|
|
106
153
|
def self.mson_to_ast_json(filename)
|
@@ -112,24 +159,26 @@ module Lacerda
|
|
112
159
|
unless mson[/^\#[ ]*data[ ]+structure/i]
|
113
160
|
mson = "# Data Structures\n#{mson}"
|
114
161
|
end
|
162
|
+
result = LoungeLizard.parse(mson)
|
163
|
+
File.open(output, 'w'){ |f| f.puts(result) }
|
164
|
+
output
|
165
|
+
end
|
115
166
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
status = -1
|
121
|
-
result = ''
|
122
|
-
|
123
|
-
unless parse_result.null?
|
124
|
-
status = 0
|
125
|
-
result = parse_result.read_string
|
126
|
-
end
|
167
|
+
private_class_method def self.ast_parsing_errors(filename)
|
168
|
+
ast_parsing_annotation_messages(filename, 'error')
|
169
|
+
end
|
127
170
|
|
128
|
-
|
171
|
+
# Reads a file containing a json representation of a blueprint AST file,
|
172
|
+
# and returns the content of a parse result.
|
173
|
+
# It always returns an array.
|
174
|
+
private_class_method def self.parse_result_contents_from_ast_file(filename)
|
175
|
+
json = JSON.parse(open(filename).read)
|
176
|
+
json&.dig('content') || []
|
177
|
+
end
|
129
178
|
|
130
|
-
|
131
|
-
|
132
|
-
|
179
|
+
private_class_method def self.annotations_from_blueprint_ast(filename)
|
180
|
+
elements = parse_result_contents_from_ast_file(filename)
|
181
|
+
elements.select { |element| element['element'] == 'annotation' }
|
133
182
|
end
|
134
183
|
end
|
135
184
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module Lacerda
|
3
2
|
module Conversion
|
4
3
|
class DataStructure
|
@@ -48,49 +47,53 @@ module Lacerda
|
|
48
47
|
private
|
49
48
|
|
50
49
|
def add_description_to_json_schema
|
51
|
-
return unless @data
|
52
|
-
description = @data
|
50
|
+
return unless @data
|
51
|
+
description = @data.detect { |c| c.dig('meta', 'description') }
|
53
52
|
return unless description
|
54
|
-
@schema['description'] = description['
|
53
|
+
@schema['description'] = description['meta']['description'].strip
|
55
54
|
end
|
56
55
|
|
57
56
|
def add_properties_to_json_schema
|
58
|
-
|
59
|
-
return unless
|
60
|
-
|
61
|
-
|
57
|
+
possible_members = @data&.first&.dig('content')
|
58
|
+
return unless possible_members
|
59
|
+
# In the case that you create a nested data structure when type == 'object',
|
60
|
+
# the possible_members can be just a Hash, instead of an array
|
61
|
+
possible_members = [possible_members] if possible_members.is_a?(Hash)
|
62
|
+
members = possible_members.select { |d| d['element'] == 'member' }
|
62
63
|
# Iterate over each property
|
63
64
|
members.each do |s|
|
64
65
|
|
65
66
|
# Pluck some things out of the AST
|
66
67
|
content = s['content']
|
67
|
-
type_definition = content['
|
68
|
-
type = type_definition['
|
69
|
-
attributes =
|
68
|
+
type_definition = content['value']
|
69
|
+
type = type_definition['element']
|
70
|
+
attributes = s.dig('attributes', 'typeAttributes') || []
|
70
71
|
is_required = attributes.include?('required')
|
71
72
|
|
72
73
|
# Prepare the json schema fragment
|
73
74
|
spec = {}
|
74
|
-
name = Lacerda.underscore(content['
|
75
|
+
name = Lacerda.underscore(content['key']['content'])
|
75
76
|
|
76
77
|
# This is either type: primimtive or a oneOf { $ref: reference_name }
|
77
78
|
spec.merge!(primitive_or_oneOf(type, is_required))
|
78
79
|
|
79
80
|
# We might have a description
|
80
|
-
spec['description'] =
|
81
|
+
spec['description'] = s.dig('meta', 'description')
|
81
82
|
|
82
83
|
# If it's an array, we need to pluck out the item types
|
83
84
|
if type == 'array'
|
84
|
-
nestedTypes = type_definition['
|
85
|
+
nestedTypes = type_definition['content'].map{|vc| vc['element'] }.uniq
|
85
86
|
spec['items'] = array_items(nestedTypes)
|
86
87
|
|
87
88
|
# If it's an object, we need recursion
|
88
89
|
elsif type == 'object'
|
89
90
|
spec['properties'] = {}
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
91
|
+
# The object has a value that will represent a data structure. the data
|
92
|
+
# passed to DataStructure normally is an array, but in this case if wouldn't
|
93
|
+
# So we have to wrap it if it's not an Array.
|
94
|
+
data = [content['value']] unless content['value'].is_a?(Array)
|
95
|
+
data_structure = DataStructure.new('tmp', [content['value']], @scope).to_json
|
96
|
+
spec['properties'].merge!(data_structure['properties'])
|
94
97
|
end
|
95
98
|
|
96
99
|
# Add the specification of this property to the schema
|
@@ -154,7 +157,7 @@ module Lacerda
|
|
154
157
|
end
|
155
158
|
|
156
159
|
def reference(type)
|
157
|
-
{'$ref' => "#/definitions/#{self.class.scope(@scope, type
|
160
|
+
{'$ref' => "#/definitions/#{self.class.scope(@scope, type)}" }
|
158
161
|
end
|
159
162
|
|
160
163
|
def json_schema_blueprint
|
data/lib/lacerda/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lacerda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jannis Hermanns
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -53,47 +53,53 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 2.6.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: colorize
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0
|
61
|
+
version: '0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: blumquist
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
75
|
+
version: '0.5'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
82
|
+
version: '0.5'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: lounge_lizard
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.1.3
|
87
90
|
- - "~>"
|
88
91
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0.
|
92
|
+
version: '0.1'
|
90
93
|
type: :runtime
|
91
94
|
prerelease: false
|
92
95
|
version_requirements: !ruby/object:Gem::Requirement
|
93
96
|
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 0.1.3
|
94
100
|
- - "~>"
|
95
101
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0.
|
102
|
+
version: '0.1'
|
97
103
|
- !ruby/object:Gem::Dependency
|
98
104
|
name: tins
|
99
105
|
requirement: !ruby/object:Gem::Requirement
|