apitecto 0.0.1
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 +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +7 -0
- data/apitecto.gemspec +26 -0
- data/lib/apitecto.rb +304 -0
- data/lib/apitecto/version.rb +3 -0
- data/spec/apitecto_spec.rb +11 -0
- data/spec/spec_helper.rb +2 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bd83508eada2e33298523b90167c48faa0bcd81d
|
4
|
+
data.tar.gz: b8cefda97c4f6f322c5574299a12738d470deca5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2a2fa4f1116f036edac8c3e6bf42305024361e631ad58208a5f51249e3ab2a1329f0d42ffeae464593b71220d2a5aab07fd604329678d8726d69f7bb8ce60c9e
|
7
|
+
data.tar.gz: 3b0ffd44e28c115e7fcc07870b4c1fdaf8f4a8b6c0ee2820cdef244c251582a35729925973c6867509c4cf649f0282ad2dd1bb6c5c3c784e41223300cc0e14c3
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Roberto Quintanilla
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Apitecto
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'apitecto'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install apitecto
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it ( https://github.com/vovimayhem/apitecto/fork )
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/apitecto.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'apitecto/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "apitecto"
|
8
|
+
spec.version = Apitecto::VERSION
|
9
|
+
spec.authors = ["Roberto Quintanilla"]
|
10
|
+
spec.email = ["roberto.quintanilla@gmail.com"]
|
11
|
+
spec.summary = %q{A ruby library for generating REST Api documentation using API Blueprint}
|
12
|
+
spec.description = %q{A ruby library for generating REST Api documentation using API Blueprint}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "matter_compiler", "~> 0.5"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
end
|
data/lib/apitecto.rb
ADDED
@@ -0,0 +1,304 @@
|
|
1
|
+
require "apitecto/version"
|
2
|
+
require "matter_compiler/blueprint"
|
3
|
+
|
4
|
+
module Apitecto
|
5
|
+
mattr_reader :blueprints, :lines_of_spec
|
6
|
+
mattr_accessor :output_dir
|
7
|
+
|
8
|
+
def self.blueprints; @@blueprints ||= {}; end
|
9
|
+
def self.blueprint_exists?(blueprint_name); blueprints.has_key?(blueprint_name); end
|
10
|
+
|
11
|
+
|
12
|
+
def self.lines_of_spec; @@lines_of_spec ||= {}; end
|
13
|
+
def self.get_lines_of_spec(spec_file_path)
|
14
|
+
unless lines_of_spec[spec_file_path].present?
|
15
|
+
lines_of_spec[spec_file_path] = File.read(spec_file_path).each_line.to_a.map(&:strip).inject({}) do |lines, line|
|
16
|
+
lines[lines.values.count + 1] = (line =~ /\A#/i || line == "") ? (line == "" ? "" : line[1..-1]) : nil
|
17
|
+
lines
|
18
|
+
end
|
19
|
+
end
|
20
|
+
lines_of_spec[spec_file_path]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
RSpec.configure do |config|
|
25
|
+
|
26
|
+
config.before(:suite) do
|
27
|
+
Apitecto.output_dir = File.join((defined?(Rails) ? Rails.root : File.expand_path('.')), 'doc')
|
28
|
+
end
|
29
|
+
|
30
|
+
# Formar el AST de Blueprint a partir de los examples de request...
|
31
|
+
config.after(:each, type: :request) do |rspec_example|
|
32
|
+
|
33
|
+
if rspec_example.metadata[:rest_api_name].present?
|
34
|
+
|
35
|
+
################################################################################################
|
36
|
+
#
|
37
|
+
lines_of_spec = Apitecto.get_lines_of_spec rspec_example.metadata[:file_path]
|
38
|
+
|
39
|
+
##############################################################################
|
40
|
+
# Find or create the Root AST node:
|
41
|
+
rest_api_name = rspec_example.metadata[:rest_api_name] || :default
|
42
|
+
rest_api_key = rest_api_name.to_s.downcase.split.join("-").dasherize
|
43
|
+
|
44
|
+
blueprint_ast = if Apitecto.blueprint_exists? rest_api_key
|
45
|
+
Apitecto.blueprints[rest_api_key]
|
46
|
+
else
|
47
|
+
Apitecto.blueprints[rest_api_key] = { name: rest_api_name, description: nil, resourceGroups: [] }
|
48
|
+
end
|
49
|
+
|
50
|
+
blueprint_ast[:description] = blueprint_ast[:description] || rspec_example.metadata[:rest_api_description]
|
51
|
+
|
52
|
+
##############################################################################################
|
53
|
+
# Find the rspec_example's Example Groups metadata mappable to
|
54
|
+
# API Blueprint's Resource Group, Resource and Action:
|
55
|
+
rspec_action_metadata = rspec_example.metadata[:example_group]
|
56
|
+
rspec_resource_metadata = rspec_action_metadata[:parent_example_group]
|
57
|
+
rspec_resource_group_metadata = rspec_resource_metadata[:parent_example_group]
|
58
|
+
|
59
|
+
##############################################################################################
|
60
|
+
# Retrieve or form the resource group AST:
|
61
|
+
|
62
|
+
# ...find:
|
63
|
+
resource_group_ast = blueprint_ast[:resourceGroups].detect do |resource_group|
|
64
|
+
resource_group[:rspec_file_path] == rspec_resource_group_metadata[:file_path]
|
65
|
+
end
|
66
|
+
|
67
|
+
# ...create unless found:
|
68
|
+
unless resource_group_ast.present?
|
69
|
+
resource_group_comment_end_line_number = rspec_resource_group_metadata[:line_number]
|
70
|
+
resource_group_comment_start_line_number = resource_group_comment_end_line_number
|
71
|
+
while (!lines_of_spec[resource_group_comment_start_line_number-1].nil?) do
|
72
|
+
resource_group_comment_start_line_number -= 1
|
73
|
+
end
|
74
|
+
|
75
|
+
resource_group_comment_range = resource_group_comment_start_line_number..resource_group_comment_end_line_number
|
76
|
+
resource_group_comment_lines = lines_of_spec.select { |key| resource_group_comment_range.include? key }.values.compact
|
77
|
+
|
78
|
+
resource_group_name = resource_group_comment_lines.detect { |line| line =~ /\A#\s+(.+)/i }
|
79
|
+
resource_group_name = $1 unless resource_group_name.blank?
|
80
|
+
resource_group_name = rspec_resource_group_metadata[:description] unless resource_group_name.present?
|
81
|
+
|
82
|
+
resource_group_description = resource_group_comment_lines.select { |line| line !~ /\A#|\s+\+/i }.map(&:strip)
|
83
|
+
resource_group_description.shift if resource_group_description.first.blank?
|
84
|
+
resource_group_description.pop if resource_group_description.last.blank?
|
85
|
+
resource_group_description = resource_group_description.join("\n")
|
86
|
+
|
87
|
+
resource_group_sort_order = rspec_resource_group_metadata[:doc_sort_order] || 90000000000000
|
88
|
+
|
89
|
+
blueprint_ast[:resourceGroups] << {
|
90
|
+
sort_order: resource_group_sort_order, # Ignored as it's not part of the API Blueprint AST
|
91
|
+
rspec_file_path: rspec_resource_group_metadata[:file_path], # Ignored as it's not part of the API Blueprint AST
|
92
|
+
name: resource_group_name,
|
93
|
+
description: resource_group_description,
|
94
|
+
resources: []
|
95
|
+
}
|
96
|
+
resource_group_ast = blueprint_ast[:resourceGroups].last
|
97
|
+
end
|
98
|
+
|
99
|
+
##############################################################################################
|
100
|
+
# Retrieve or form the example's resource AST:
|
101
|
+
|
102
|
+
# ...find:
|
103
|
+
resource_ast = resource_group_ast[:resources].detect do |r|
|
104
|
+
r[:sort_order] == rspec_resource_metadata[:line_number]
|
105
|
+
end
|
106
|
+
|
107
|
+
# ...create unless found:
|
108
|
+
unless resource_ast.present?
|
109
|
+
|
110
|
+
resource_comment_start_line_number = rspec_resource_metadata[:line_number]
|
111
|
+
while (!lines_of_spec[resource_comment_start_line_number-1].nil?) do
|
112
|
+
resource_comment_start_line_number -= 1
|
113
|
+
end
|
114
|
+
|
115
|
+
resource_comment_range = resource_comment_start_line_number..rspec_resource_metadata[:line_number]
|
116
|
+
resource_comment_lines = lines_of_spec.select { |key| resource_comment_range.include? key }.values.compact
|
117
|
+
|
118
|
+
resource_name = resource_comment_lines.detect { |line| line =~ /\A#\s+(.+)\[(.+)\]/i }
|
119
|
+
resource_name = $1.strip unless resource_name.blank?
|
120
|
+
resource_uri_template = $2.strip unless resource_name.blank?
|
121
|
+
|
122
|
+
# Name & UriTemplate last try... rspec example_group metadata:
|
123
|
+
resource_name = rspec_resource_metadata[:description] unless resource_name.present?
|
124
|
+
resource_uri_template = rspec_resource_metadata[:uri_template] unless resource_uri_template.present?
|
125
|
+
|
126
|
+
resource_description = resource_comment_lines.select { |line| line !~ /\A#|\s+\+/i }.map(&:strip)
|
127
|
+
resource_description.shift if resource_description.first.blank?
|
128
|
+
resource_description.pop if resource_description.last.blank?
|
129
|
+
resource_description = resource_description.join("\n")
|
130
|
+
|
131
|
+
resource_group_ast[:resources] << {
|
132
|
+
sort_order: rspec_resource_metadata[:line_number], # Ignored as it's not part of the API Blueprint AST
|
133
|
+
name: resource_name,
|
134
|
+
description: resource_description, # TODO: Extract from somewhere, or default to...
|
135
|
+
|
136
|
+
uriTemplate: resource_uri_template,
|
137
|
+
model: nil, # No Model, as rspec request examples generate some output.
|
138
|
+
parameters: [],
|
139
|
+
actions: []
|
140
|
+
}
|
141
|
+
|
142
|
+
resource_ast = resource_group_ast[:resources].last
|
143
|
+
end
|
144
|
+
|
145
|
+
#############################################################################################
|
146
|
+
# Retrieve the rspec example's request & response:
|
147
|
+
request ||= respond_to?(:last_request) ? last_request : @request
|
148
|
+
response ||= respond_to?(:last_response) ? last_response : @response
|
149
|
+
|
150
|
+
#############################################################################################
|
151
|
+
# Retrieve or form the example's action AST:
|
152
|
+
|
153
|
+
action_ast = resource_ast[:actions].detect { |a| a[:sort_order] == rspec_action_metadata[:line_number] }
|
154
|
+
unless action_ast.present?
|
155
|
+
|
156
|
+
action_comment_start_line_number = rspec_action_metadata[:line_number]
|
157
|
+
while (!lines_of_spec[action_comment_start_line_number-1].nil?) do
|
158
|
+
action_comment_start_line_number -= 1
|
159
|
+
end
|
160
|
+
|
161
|
+
action_comment_range = action_comment_start_line_number..rspec_action_metadata[:line_number]
|
162
|
+
action_comment_lines = lines_of_spec.select { |key| action_comment_range.include? key }.values.compact
|
163
|
+
|
164
|
+
# 1st try: Group Comments in MD:
|
165
|
+
action_name = action_comment_lines.detect { |line| line =~ /\A#\s+(.+)\[(.+)\]/i }
|
166
|
+
action_name = $1.strip unless action_name.blank?
|
167
|
+
action_method = $2.strip unless action_name.blank?
|
168
|
+
|
169
|
+
# 2nd try: extract the method from the RSpec Example Group Metadata's description:
|
170
|
+
action_method = $1.strip if action_method.blank? && rspec_action_metadata[:description] =~ /\A(GET|POST|PUT|PATCH|DELETE)\s/
|
171
|
+
|
172
|
+
# Last try: extract the method from a custom metadata tag:
|
173
|
+
action_method = rspec_action_metadata[:method] if action_method.blank?
|
174
|
+
|
175
|
+
# abort ast if no method was found...
|
176
|
+
if action_method.present?
|
177
|
+
|
178
|
+
action_description = action_comment_lines.select { |line| line !~ /\A#|\s+\+/i }.map(&:strip)
|
179
|
+
action_description.shift if action_description.first.blank?
|
180
|
+
action_description.pop if action_description.last.blank?
|
181
|
+
action_description = action_description.join("\n")
|
182
|
+
|
183
|
+
resource_ast[:actions] << {
|
184
|
+
sort_order: rspec_action_metadata[:line_number], # Ignored as it's not part of the API Blueprint AST
|
185
|
+
name: action_name,
|
186
|
+
description: action_description,
|
187
|
+
method: action_method,
|
188
|
+
parameters: [], # TODO: Extract from somewhere, or default to...
|
189
|
+
examples: []
|
190
|
+
}
|
191
|
+
action_ast = resource_ast[:actions].last
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
if action_ast.present?
|
196
|
+
|
197
|
+
##############################################################################################
|
198
|
+
# Form the transaction example AST + add request & response AST's
|
199
|
+
example_comment_start_line_number = rspec_example.metadata[:line_number]
|
200
|
+
while (!lines_of_spec[example_comment_start_line_number-1].nil?) do
|
201
|
+
example_comment_start_line_number -= 1
|
202
|
+
end
|
203
|
+
|
204
|
+
example_comment_range = example_comment_start_line_number..rspec_example.metadata[:line_number]
|
205
|
+
example_comment_lines = lines_of_spec.select { |key| example_comment_range.include? key }.values.compact
|
206
|
+
|
207
|
+
# 1st try: Group Comments in MD:
|
208
|
+
example_name = example_comment_lines.detect { |line| line =~ /\A#\s+(.+)\s+\((.+)\)|#\s+(.+)\z/i }
|
209
|
+
example_content_type = $2.strip if example_name.present? && $2.present?
|
210
|
+
example_name = ($1 || $3).strip unless example_name.blank?
|
211
|
+
|
212
|
+
# Last try: extract the example_name from the rspec_example metadata description:
|
213
|
+
example_name = rspec_example.metadata[:description] if example_name.blank?
|
214
|
+
example_content_type = request.headers["CONTENT_TYPE"] unless example_content_type.present?
|
215
|
+
|
216
|
+
example_content_type = example_content_type.present? ? "(#{example_content_type})" : ""
|
217
|
+
#example_name = "#{example_name} #{example_content_type}".strip
|
218
|
+
|
219
|
+
example_description = example_comment_lines.select { |line| line !~ /\A#|\s+\+/i }.map(&:strip)
|
220
|
+
example_description.shift if example_description.first.blank?
|
221
|
+
example_description.pop if example_description.last.blank?
|
222
|
+
example_description = example_description.join("\n")
|
223
|
+
|
224
|
+
##############################################################################################
|
225
|
+
# Form the request AST:
|
226
|
+
request_ast = {
|
227
|
+
name: example_name,
|
228
|
+
description: example_description,
|
229
|
+
parameters: [], # TODO: Extract from somewhere, or default to...
|
230
|
+
|
231
|
+
# Filter headers from the request.headers (env) hash, convert header names:
|
232
|
+
headers: request.headers.select { |k,v| (k =~ /\AHTTP_/ && k !~ /HOST|COOKIE|USER_AGENT\z/i) || k == "CONTENT_TYPE" }
|
233
|
+
.map { |k, v| { name: (k == "CONTENT_TYPE" ? k : k[5..-1]).titleize.split().join('-'), value: v } },
|
234
|
+
body: request.body.read,
|
235
|
+
schema: nil # TODO: Extract from somewhere, or default to...
|
236
|
+
}
|
237
|
+
|
238
|
+
##############################################################################################
|
239
|
+
# Form the response AST Hash:
|
240
|
+
|
241
|
+
response_name = response.status # TODO: el status es sufijo? Se puede agregar mas palabras?
|
242
|
+
|
243
|
+
response_ast = {
|
244
|
+
name: response_name,
|
245
|
+
parameters: [], # TODO: Extract from somewhere, or default to...
|
246
|
+
|
247
|
+
# Assign the response headers
|
248
|
+
# TODO: Filter-out irrelevant headers:
|
249
|
+
headers: response.headers.select { |k,v| k !~ /\AX-/i && k !~ /Cookie\z/i }
|
250
|
+
.map { |k, v| { name: k, value: v } },
|
251
|
+
body: response.body,
|
252
|
+
schema: nil # TODO: Extract from somewhere, or default to...
|
253
|
+
}
|
254
|
+
|
255
|
+
#########################################################################################################
|
256
|
+
|
257
|
+
transaction_example_ast = {
|
258
|
+
sort_order: rspec_example.metadata[:line_number], # Ignored as it's not part of the API Blueprint AST
|
259
|
+
#name: example_name,
|
260
|
+
#description: example_description,
|
261
|
+
requests: [ request_ast ],
|
262
|
+
responses: [ response_ast ]
|
263
|
+
}
|
264
|
+
|
265
|
+
# append the transaction_example_ast
|
266
|
+
action_ast[:examples] << transaction_example_ast
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# Escribir los archivos a partir de los AST's recolectados
|
272
|
+
config.after(:suite) do
|
273
|
+
|
274
|
+
Apitecto.blueprints.each do |api_name, blueprint_ast|
|
275
|
+
|
276
|
+
# RSpec corre los ejemplos en random order (eso es bueno para las pruebas... pero malo para documentacion)
|
277
|
+
# Ordenar los resource groups, resources, actions y examples del AST por su sort_order:
|
278
|
+
sorter = ->(x,y) { x[:sort_order] <=> y[:sort_order] }
|
279
|
+
|
280
|
+
blueprint_ast[:resourceGroups].each do |resource_group_ast|
|
281
|
+
resource_group_ast[:resources].each do |resource_ast|
|
282
|
+
resource_ast[:actions].each do |action_ast|
|
283
|
+
action_ast[:examples].sort!(&sorter)
|
284
|
+
end
|
285
|
+
resource_ast[:actions].sort!(&sorter)
|
286
|
+
end
|
287
|
+
resource_group_ast[:resources].sort!(&sorter)
|
288
|
+
end
|
289
|
+
blueprint_ast[:resourceGroups].sort!(&sorter)
|
290
|
+
|
291
|
+
# Generar el directorio a partir del nombre del api:
|
292
|
+
api_docs_path = File.join(Apitecto.output_dir, api_name)
|
293
|
+
Dir.mkdir(api_docs_path) unless Dir.exists?(api_docs_path)
|
294
|
+
|
295
|
+
# Generar el archivo de API Blueprint:
|
296
|
+
api_blueprint_path = File.join(api_docs_path, "api_blueprint.md")
|
297
|
+
|
298
|
+
blueprint = MatterCompiler::Blueprint.new(blueprint_ast)
|
299
|
+
|
300
|
+
File.open(api_blueprint_path, "w") { |f| f.write blueprint.serialize }
|
301
|
+
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: apitecto
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Roberto Quintanilla
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: matter_compiler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.7'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: A ruby library for generating REST Api documentation using API Blueprint
|
70
|
+
email:
|
71
|
+
- roberto.quintanilla@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .rspec
|
78
|
+
- .travis.yml
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- apitecto.gemspec
|
84
|
+
- lib/apitecto.rb
|
85
|
+
- lib/apitecto/version.rb
|
86
|
+
- spec/apitecto_spec.rb
|
87
|
+
- spec/spec_helper.rb
|
88
|
+
homepage: ''
|
89
|
+
licenses:
|
90
|
+
- MIT
|
91
|
+
metadata: {}
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 2.0.14
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: A ruby library for generating REST Api documentation using API Blueprint
|
112
|
+
test_files:
|
113
|
+
- spec/apitecto_spec.rb
|
114
|
+
- spec/spec_helper.rb
|