rocket_docs 0.0.2
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/MIT-LICENSE +20 -0
- data/Rakefile +24 -0
- data/app/assets/javascripts/rocket_docs/application.js +206 -0
- data/app/assets/stylesheets/rocket_docs/application.scss +51 -0
- data/app/controllers/rocket_docs/application_controller.rb +13 -0
- data/app/helpers/rocket_docs/application_helper.rb +24 -0
- data/app/views/docs/rocket_docs/_action.markdown.erb +23 -0
- data/app/views/docs/rocket_docs/_action.slim +43 -0
- data/app/views/docs/rocket_docs/_controller.markdown.erb +7 -0
- data/app/views/docs/rocket_docs/_controller.slim +9 -0
- data/app/views/docs/rocket_docs/_documentation.markdown.erb +4 -0
- data/app/views/docs/rocket_docs/_documentation.slim +3 -0
- data/app/views/docs/rocket_docs/_hash_param.slim +7 -0
- data/app/views/docs/rocket_docs/_version.slim +7 -0
- data/app/views/docs/rocket_docs/index.slim +3 -0
- data/app/views/docs/rocket_docs/show.markdown.erb +3 -0
- data/app/views/docs/rocket_docs/show.slim +4 -0
- data/app/views/layouts/rocket_docs/_modal.slim +12 -0
- data/app/views/layouts/rocket_docs/_navigation.slim +10 -0
- data/app/views/layouts/rocket_docs/application.slim +9 -0
- data/config/routes.rb +5 -0
- data/lib/rocket_docs/documentation/action.rb +98 -0
- data/lib/rocket_docs/documentation/controller.rb +57 -0
- data/lib/rocket_docs/documentation.rb +46 -0
- data/lib/rocket_docs/engine.rb +12 -0
- data/lib/rocket_docs/parser.rb +105 -0
- data/lib/rocket_docs/router.rb +86 -0
- data/lib/rocket_docs/version.rb +3 -0
- data/lib/rocket_docs.rb +30 -0
- data/lib/tasks/rocket_docs_tasks.rake +85 -0
- metadata +284 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 97e8e49ad6cf5ad899dd4e256ea5ef36e34f259b
|
4
|
+
data.tar.gz: 4b7ed20c4cdb13d88576684948e01d903be40665
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c5c728791f5e8e6d2590e0fac023314a962c2b2fa211d2b6bd1ecd9b0087430a430e3d2337cfe35c449104bb0ed0ca3587847d5230b1974c36d2c501ac28b51b
|
7
|
+
data.tar.gz: dbd9b9939b76bcf4a00c14b8b775a66e0fdbd5062be68a96f5125545f5cd285d6e1cc27af65cfb033c9a379d353324eecd0993774734a83474ffb493caf75fcd
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'rdoc/task'
|
9
|
+
|
10
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
11
|
+
rdoc.rdoc_dir = 'rdoc'
|
12
|
+
rdoc.title = 'RocketDocs'
|
13
|
+
rdoc.options << '--line-numbers'
|
14
|
+
rdoc.rdoc_files.include('README.rdoc')
|
15
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
16
|
+
end
|
17
|
+
|
18
|
+
APP_RAKEFILE = File.expand_path('../spec/test_app/Rakefile', __FILE__)
|
19
|
+
load 'rails/tasks/engine.rake'
|
20
|
+
|
21
|
+
Bundler::GemHelper.install_tasks
|
22
|
+
|
23
|
+
RSpec::Core::RakeTask.new(:spec)
|
24
|
+
task default: :appraisal if !ENV['APPRAISAL_INITIALIZED'] && !ENV['TRAVIS']
|
@@ -0,0 +1,206 @@
|
|
1
|
+
//= require jquery
|
2
|
+
//= require jquery_ujs
|
3
|
+
//= require bootstrap
|
4
|
+
|
5
|
+
$(document).ready(function () {
|
6
|
+
$('#try-out-modal').on('show.bs.modal', function (event) {
|
7
|
+
var $modal = $(this);
|
8
|
+
var $triggerButton = $(event.relatedTarget);
|
9
|
+
var $testButton = $modal.find('.btn.try');
|
10
|
+
$modal.find('h4.modal-title').text('' +
|
11
|
+
$triggerButton.data('request-method') + ' ' + $triggerButton.data('url')
|
12
|
+
);
|
13
|
+
$modal.find('.modal-body').html(
|
14
|
+
contentForModal(
|
15
|
+
$triggerButton.data('url'),
|
16
|
+
$triggerButton.data('request-method'),
|
17
|
+
$triggerButton.data('params'),
|
18
|
+
$triggerButton.data('saved_params'),
|
19
|
+
$triggerButton.data('saved_text')
|
20
|
+
)
|
21
|
+
);
|
22
|
+
$testButton.click(function(){
|
23
|
+
saveParams($modal.find('.modal-body'), $triggerButton);
|
24
|
+
var $response = $modal.find('.response');
|
25
|
+
|
26
|
+
$modal.find('.response-body').removeClass('hidden');
|
27
|
+
addSpinner($response);
|
28
|
+
|
29
|
+
$.ajax(
|
30
|
+
buildRequestParams($modal.find('.modal-body'), $triggerButton.data('url'), $triggerButton.data('request-method'))
|
31
|
+
).done(function(data, textStatus, jqXHR) {
|
32
|
+
var response = jqXHR.responseText;
|
33
|
+
|
34
|
+
$response.html('');
|
35
|
+
$response.text(response);
|
36
|
+
$(window).trigger('resize');
|
37
|
+
});
|
38
|
+
});
|
39
|
+
}).on('hidden.bs.modal', function () {
|
40
|
+
var $modal = $(this);
|
41
|
+
$modal.find('h4.modal-title').text('Try it');
|
42
|
+
$modal.find('.modal-body').html('');
|
43
|
+
});
|
44
|
+
|
45
|
+
function buildRequestParams($object, url, method) {
|
46
|
+
var $inputs = $object.find('input[data-key]');
|
47
|
+
var $requestBody = $object.find('textarea');
|
48
|
+
var data = null;
|
49
|
+
var processData = true;
|
50
|
+
|
51
|
+
if ($inputs.length !== 0) {
|
52
|
+
data = {};
|
53
|
+
$inputs.each(function(i, $input) {
|
54
|
+
$input = $($input);
|
55
|
+
if (url.indexOf('{' + $input.data('key') + '}')) {
|
56
|
+
url = url.replace('{' + $input.data('key') + '}', $input.val());
|
57
|
+
} else {
|
58
|
+
data[$input.data('key')] = $input.val();
|
59
|
+
}
|
60
|
+
});
|
61
|
+
}
|
62
|
+
if ($requestBody.length !== 0) {
|
63
|
+
processData = false;
|
64
|
+
data = $requestBody.val();
|
65
|
+
}
|
66
|
+
|
67
|
+
return {
|
68
|
+
url: url,
|
69
|
+
type: method,
|
70
|
+
processData: processData,
|
71
|
+
data: data
|
72
|
+
};
|
73
|
+
}
|
74
|
+
|
75
|
+
function saveParams($object, $saveToObject) {
|
76
|
+
var $inputs = $object.find('input[data-key]');
|
77
|
+
var $requestBody = $object.find('textarea');
|
78
|
+
|
79
|
+
if ($inputs.length !== 0) {
|
80
|
+
var params = {};
|
81
|
+
$inputs.each(function(i, $input) {
|
82
|
+
$input = $($input);
|
83
|
+
params[$input.data('key')] = $input.val();
|
84
|
+
});
|
85
|
+
$saveToObject.data('saved_params', params);
|
86
|
+
}
|
87
|
+
|
88
|
+
if ($requestBody.length !== 0) {
|
89
|
+
$saveToObject.data('saved_text', $requestBody.val());
|
90
|
+
}
|
91
|
+
|
92
|
+
return true;
|
93
|
+
}
|
94
|
+
|
95
|
+
function addSpinner($object) {
|
96
|
+
var message = '<center>'+
|
97
|
+
'<span class="glyphicon glyphicon-refresh gly-spin"></span>'+
|
98
|
+
' Waiting for response...'+
|
99
|
+
'</center>';
|
100
|
+
$object.html(message);
|
101
|
+
}
|
102
|
+
|
103
|
+
function contentForModal(url, method, params, savedParams, savedText) {
|
104
|
+
var content = '';
|
105
|
+
content += '<h3>Request body</h3>';
|
106
|
+
if (method === 'GET' && params) {
|
107
|
+
content += paramsInputTable(params, savedParams);
|
108
|
+
} else {
|
109
|
+
var regex = /\{[^\s]+\}/;
|
110
|
+
var match = regex.exec(url);
|
111
|
+
if (match && match.length !== 0) {
|
112
|
+
var tempParams = {};
|
113
|
+
$.each(match, function(i, m) {
|
114
|
+
tempParams[m.replace(/[\{\}]/g,'')] = i;
|
115
|
+
});
|
116
|
+
content += paramsInputTable(tempParams, savedParams);
|
117
|
+
}
|
118
|
+
var saved = '';
|
119
|
+
if (savedText) {
|
120
|
+
saved = savedText;
|
121
|
+
}
|
122
|
+
content += '<textarea class="form-control" rows="6" cols="90">' + saved + '</textarea>';
|
123
|
+
}
|
124
|
+
if (method !== 'GET' && params) {
|
125
|
+
content += '<h4>Expected params</h4>';
|
126
|
+
content += paramsTable(params);
|
127
|
+
}
|
128
|
+
content += '<div class="response-body hidden">';
|
129
|
+
content += '<hr>';
|
130
|
+
content += '<h3>Response</h3>';
|
131
|
+
content += '<pre><code class="response"></code></pre>';
|
132
|
+
content += '</div>';
|
133
|
+
|
134
|
+
return content;
|
135
|
+
}
|
136
|
+
|
137
|
+
function paramsInputTable(params, savedParams) {
|
138
|
+
var content = '<table class="table table-striped">';
|
139
|
+
content += '<thead>';
|
140
|
+
content += '<tr>'+
|
141
|
+
'<th>Param</th>'+
|
142
|
+
'<th>Value</th>'+
|
143
|
+
'</tr>';
|
144
|
+
content += '</thead>';
|
145
|
+
$.each(params, function(k, v) {
|
146
|
+
content += paramsInputTableRow(k, v, null, savedParams);
|
147
|
+
});
|
148
|
+
content += '</table>';
|
149
|
+
return content;
|
150
|
+
}
|
151
|
+
|
152
|
+
function paramsInputTableRow(k, v, wrapper, savedParams) {
|
153
|
+
var content = '';
|
154
|
+
var saved = '';
|
155
|
+
if (wrapper) {
|
156
|
+
k = wrapper + '[' + k + ']';
|
157
|
+
}
|
158
|
+
if (savedParams && savedParams[k]) {
|
159
|
+
saved = savedParams[k];
|
160
|
+
}
|
161
|
+
if (typeof v === 'object') {
|
162
|
+
$.each(v, function(kk, vv) {
|
163
|
+
content += paramsInputTableRow(kk, vv, k, savedParams);
|
164
|
+
});
|
165
|
+
} else {
|
166
|
+
content += '<tr>'+
|
167
|
+
'<td>' + k + '</td>'+
|
168
|
+
'<td><input type="text" class="form-control" value="' + saved + '" data-key="' + k + '"></td>'+
|
169
|
+
'</tr>';
|
170
|
+
}
|
171
|
+
return content;
|
172
|
+
}
|
173
|
+
|
174
|
+
function paramsTable(params) {
|
175
|
+
var content = '<table class="table table-striped">';
|
176
|
+
content += '<thead>';
|
177
|
+
content += '<tr>'+
|
178
|
+
'<th>Name</th>'+
|
179
|
+
'<th>Type</th>'+
|
180
|
+
'</tr>';
|
181
|
+
content += '</thead>';
|
182
|
+
$.each(params, function(k, v){
|
183
|
+
content += paramsTableRow(k, v, null);
|
184
|
+
});
|
185
|
+
content += '</table>';
|
186
|
+
return content;
|
187
|
+
}
|
188
|
+
|
189
|
+
function paramsTableRow(k, v, wrapper) {
|
190
|
+
var content = '';
|
191
|
+
if (wrapper) {
|
192
|
+
k = wrapper + '[' + k + ']';
|
193
|
+
}
|
194
|
+
if (typeof v === 'object') {
|
195
|
+
$.each(v, function(kk, vv) {
|
196
|
+
content += paramsTableRow(kk, vv, k);
|
197
|
+
});
|
198
|
+
} else {
|
199
|
+
content += '<tr>'+
|
200
|
+
'<td>' + k + '</td>'+
|
201
|
+
'<td>' + v + '</td>'+
|
202
|
+
'</tr>';
|
203
|
+
}
|
204
|
+
return content;
|
205
|
+
}
|
206
|
+
});
|
@@ -0,0 +1,51 @@
|
|
1
|
+
/*
|
2
|
+
*= require_tree .
|
3
|
+
*= require_self
|
4
|
+
*/
|
5
|
+
@import "bootstrap-sprockets";
|
6
|
+
@import "bootstrap";
|
7
|
+
|
8
|
+
body {
|
9
|
+
padding-top: 70px;
|
10
|
+
}
|
11
|
+
|
12
|
+
.gly-spin {
|
13
|
+
-webkit-animation: spin 2s infinite linear;
|
14
|
+
-moz-animation: spin 2s infinite linear;
|
15
|
+
-o-animation: spin 2s infinite linear;
|
16
|
+
animation: spin 2s infinite linear;
|
17
|
+
}
|
18
|
+
@-moz-keyframes spin {
|
19
|
+
0% {
|
20
|
+
-moz-transform: rotate(0deg);
|
21
|
+
}
|
22
|
+
100% {
|
23
|
+
-moz-transform: rotate(359deg);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
@-webkit-keyframes spin {
|
27
|
+
0% {
|
28
|
+
-webkit-transform: rotate(0deg);
|
29
|
+
}
|
30
|
+
100% {
|
31
|
+
-webkit-transform: rotate(359deg);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
@-o-keyframes spin {
|
35
|
+
0% {
|
36
|
+
-o-transform: rotate(0deg);
|
37
|
+
}
|
38
|
+
100% {
|
39
|
+
-o-transform: rotate(359deg);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
@keyframes spin {
|
43
|
+
0% {
|
44
|
+
-webkit-transform: rotate(0deg);
|
45
|
+
transform: rotate(0deg);
|
46
|
+
}
|
47
|
+
100% {
|
48
|
+
-webkit-transform: rotate(359deg);
|
49
|
+
transform: rotate(359deg);
|
50
|
+
}
|
51
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RocketDocs
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
def index
|
4
|
+
@docs = RocketDocs.documentation
|
5
|
+
render 'docs/rocket_docs/index'
|
6
|
+
end
|
7
|
+
|
8
|
+
def show
|
9
|
+
@doc = RocketDocs.documentation_for_version(params[:version])
|
10
|
+
render 'docs/rocket_docs/show'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RocketDocs
|
2
|
+
module ApplicationHelper
|
3
|
+
def doc_id(doc)
|
4
|
+
"version_#{web_safe(doc.version)}"
|
5
|
+
end
|
6
|
+
|
7
|
+
def controller_id(controller)
|
8
|
+
"#{doc_id(controller.documentation)}_controller_"\
|
9
|
+
"#{web_safe(controller.name)}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def action_id(action)
|
13
|
+
"#{controller_id(action.controller)}_action_#{web_safe(action.name)}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_id(action, method)
|
17
|
+
"#{action_id(action)}_method_#{web_safe(method)}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def web_safe(string)
|
21
|
+
string.to_s.humanize.sub(' ', '').underscore
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
### <%= action.name %>
|
2
|
+
|
3
|
+
<% action.methods.each do |method| %>
|
4
|
+
#### <%= method.upcase %>
|
5
|
+
|
6
|
+
> __URL:__ <%= '' || action.url %>
|
7
|
+
|
8
|
+
<% if action.description(method) %>
|
9
|
+
>__DESCRIPTION:__ <%= action.description(method) %>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<% if action.params(method) %>
|
13
|
+
>__PARAMS:__
|
14
|
+
|
15
|
+
>| Name | Type |
|
16
|
+
>| ---- | ---- |
|
17
|
+
<% action.params(method).each do |k, v| %>
|
18
|
+
>| <%= k %> | <%= v %> |
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
|
23
|
+
<% end %>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
.panel.panel-default
|
2
|
+
.panel-heading
|
3
|
+
h4.panel-title
|
4
|
+
= link_to "#{action.name}", "##{action_id(action)}", data: { toggle: 'collapse' }
|
5
|
+
.panel-collapse.collapse id="#{action_id(action)}"
|
6
|
+
.panel-body
|
7
|
+
ul.nav.nav-tabs
|
8
|
+
- action.methods.each_with_index do |method, index|
|
9
|
+
li class="#{index == 0 ? 'active' : ''}"
|
10
|
+
= link_to method.upcase, "##{method_id(action, method)}", data: { toggle: 'tab' }
|
11
|
+
.tab-content
|
12
|
+
- action.methods.each_with_index do |method, index|
|
13
|
+
.tab-pane class="#{index == 0 ? 'active' : ''}" id="#{method_id(action, method)}"
|
14
|
+
|
15
|
+
.col-md-6
|
16
|
+
.row
|
17
|
+
.col-xs-12
|
18
|
+
- if action.url(method)
|
19
|
+
h4 URL
|
20
|
+
= action.url
|
21
|
+
.col-xs-12
|
22
|
+
- if action.description(method)
|
23
|
+
h4 Description
|
24
|
+
= simple_format(action.description(method))
|
25
|
+
.col-md-6
|
26
|
+
.row
|
27
|
+
.col-xs-12
|
28
|
+
- if action.params(method)
|
29
|
+
h4 Params
|
30
|
+
table.table.table-striped
|
31
|
+
thead
|
32
|
+
tr
|
33
|
+
th Name
|
34
|
+
th Type
|
35
|
+
tbody
|
36
|
+
= render 'docs/rocket_docs/hash_param', hash: action.params(method), wrap: nil
|
37
|
+
|
38
|
+
- if action.url(method)
|
39
|
+
.col-xs-12
|
40
|
+
hr
|
41
|
+
= link_to '#', class: 'btn btn-primary try-out', data: { request_method: method, params: action.params(method), url: action.url, toggle: 'modal', target: '#try-out-modal' } do
|
42
|
+
span.glyphicon.glyphicon-new-window
|
43
|
+
| Try it out
|
@@ -0,0 +1,9 @@
|
|
1
|
+
.panel.panel-default
|
2
|
+
.panel-heading
|
3
|
+
h4.panel-title
|
4
|
+
= link_to "#{controller.name}", "##{controller_id(controller)}", data: { toggle: 'collapse' }
|
5
|
+
.panel-collapse.collapse id="#{controller_id(controller)}"
|
6
|
+
.panel-body
|
7
|
+
.panel-group id="#{controller_id(controller)}_accordion"
|
8
|
+
- controller.actions.each do |action|
|
9
|
+
= render 'docs/rocket_docs/action', action: action
|
@@ -0,0 +1,12 @@
|
|
1
|
+
.modal.fade#try-out-modal
|
2
|
+
.modal-dialog
|
3
|
+
.modal-content
|
4
|
+
.modal-header
|
5
|
+
button.close data-dismiss='modal'
|
6
|
+
h4.modal-title Try it
|
7
|
+
.modal-body
|
8
|
+
.modal-footer
|
9
|
+
button.btn.btn-default data-dismiss='modal'
|
10
|
+
| Close
|
11
|
+
button.btn.btn-primary.try
|
12
|
+
| Try it
|
@@ -0,0 +1,10 @@
|
|
1
|
+
- if defined?(rocket_docs)
|
2
|
+
.navbar.navbar-default.navbar-fixed-top
|
3
|
+
.container-fluid
|
4
|
+
.navbar-header
|
5
|
+
= link_to 'Documentation', rocket_docs.root_path, class: 'navbar-brand'
|
6
|
+
.collapse.navbar-collapse
|
7
|
+
ul.nav.navbar-nav
|
8
|
+
li = link_to 'All versions', rocket_docs.root_path
|
9
|
+
- RocketDocs::Router.versions.each do |v|
|
10
|
+
li = link_to v.to_s, rocket_docs.version_path(version: v)
|
data/config/routes.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
module RocketDocs
|
2
|
+
class Documentation
|
3
|
+
class Action
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :controller
|
6
|
+
attr_reader :comments
|
7
|
+
|
8
|
+
def initialize(name, comments, methods, params, controller)
|
9
|
+
@name = name
|
10
|
+
@comments = comments
|
11
|
+
@methods = sanitize_methods(methods)
|
12
|
+
@params = params
|
13
|
+
@params.delete(:version) if params
|
14
|
+
@params = @params.presence
|
15
|
+
@controller = controller
|
16
|
+
generate
|
17
|
+
end
|
18
|
+
|
19
|
+
def url(method = default_method)
|
20
|
+
(@doc[method] && @doc[method]['URL']) || @doc['URL'] ||
|
21
|
+
router_url(method)
|
22
|
+
end
|
23
|
+
|
24
|
+
def description(method = default_method)
|
25
|
+
desc = (@doc[method] && @doc[method]['DOC']) || @doc['DOC']
|
26
|
+
desc && CGI.escapeHTML(desc).gsub("\n", '<br>').html_safe
|
27
|
+
end
|
28
|
+
|
29
|
+
def params(method = default_method)
|
30
|
+
(@doc[method] && @doc[method]['PARAMS']) || @doc['PARAMS'] ||
|
31
|
+
@params
|
32
|
+
end
|
33
|
+
|
34
|
+
def default_method
|
35
|
+
methods.first || 'GET'
|
36
|
+
end
|
37
|
+
|
38
|
+
def methods
|
39
|
+
@methods.presence ||
|
40
|
+
@doc.keys.select { |m| Parser.http_keywords.include?(m) }
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def generate
|
46
|
+
return @doc = {} unless @comments.present?
|
47
|
+
@doc = RocketDocs::Parser.parse_comments(@comments).value
|
48
|
+
end
|
49
|
+
|
50
|
+
def _routes
|
51
|
+
RocketDocs::Router.app_routes
|
52
|
+
end
|
53
|
+
|
54
|
+
def sanitize_methods(methods)
|
55
|
+
return unless methods
|
56
|
+
methods.map do |m|
|
57
|
+
if m.is_a?(String)
|
58
|
+
m
|
59
|
+
else
|
60
|
+
m.to_s.sub('(?-mix:^', '').sub('$)', '').split('|')
|
61
|
+
end
|
62
|
+
end.flatten
|
63
|
+
end
|
64
|
+
|
65
|
+
def router_url(method = default_method)
|
66
|
+
route = _routes.url_for(url_params(method))
|
67
|
+
route = route.split('?').first unless method == 'GET'
|
68
|
+
CGI.unescape(route)
|
69
|
+
rescue ActionController::UrlGenerationError
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
|
73
|
+
def url_params(method = default_method)
|
74
|
+
hash = {}
|
75
|
+
hash = deflated_url_params(params(method)) if @params
|
76
|
+
hash.merge(
|
77
|
+
controller: controller.full_name.downcase,
|
78
|
+
action: name,
|
79
|
+
version: controller.documentation.version,
|
80
|
+
only_path: true
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def deflated_url_params(hash, wrapper = nil)
|
85
|
+
nh = {}
|
86
|
+
hash.each do |k, v|
|
87
|
+
new_v = wrapper ? "#{wrapper}[#{k}]" : k
|
88
|
+
if v.is_a?(Hash)
|
89
|
+
nh[k] = deflated_url_params(v, k)
|
90
|
+
else
|
91
|
+
nh[k] = "{#{new_v}}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
nh.symbolize_keys
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module RocketDocs
|
2
|
+
class Documentation
|
3
|
+
class Controller
|
4
|
+
attr_accessor :name
|
5
|
+
attr_accessor :file
|
6
|
+
attr_reader :documentation
|
7
|
+
attr_reader :actions
|
8
|
+
|
9
|
+
def initialize(name, file, actions_hash, documentation)
|
10
|
+
@file_md5 = ''
|
11
|
+
@actions = []
|
12
|
+
@actions_in = actions_hash
|
13
|
+
self.name = name
|
14
|
+
self.file = file
|
15
|
+
@documentation = documentation
|
16
|
+
update!
|
17
|
+
end
|
18
|
+
|
19
|
+
def update
|
20
|
+
should_update? && update!
|
21
|
+
end
|
22
|
+
|
23
|
+
def update!
|
24
|
+
@file_md5 = generate_hash
|
25
|
+
generate
|
26
|
+
end
|
27
|
+
|
28
|
+
def should_update?
|
29
|
+
return false if generate_hash == @file_md5
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
def name
|
34
|
+
return unless @name
|
35
|
+
@name.split('/').last.sub('_controller', '').humanize
|
36
|
+
end
|
37
|
+
|
38
|
+
def full_name
|
39
|
+
@name
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def generate
|
45
|
+
@actions = []
|
46
|
+
comments = RocketDocs::Parser.method_comments(file)
|
47
|
+
@actions_in.each do |name, action|
|
48
|
+
@actions << Action.new(name, comments[name], action[:methods], action[:params], self)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def generate_hash
|
53
|
+
Digest::MD5.file(file).hexdigest
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|