interdasting 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/MIT-LICENSE +20 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/interdasting/application.js +198 -0
- data/app/assets/stylesheets/interdasting/application.scss +51 -0
- data/app/controllers/interdasting/application_controller.rb +13 -0
- data/app/helpers/interdasting/application_helper.rb +24 -0
- data/app/views/docs/interdasting/_action.markdown.erb +23 -0
- data/app/views/docs/interdasting/_action.slim +43 -0
- data/app/views/docs/interdasting/_controller.markdown.erb +7 -0
- data/app/views/docs/interdasting/_controller.slim +9 -0
- data/app/views/docs/interdasting/_documentation.markdown.erb +4 -0
- data/app/views/docs/interdasting/_documentation.slim +3 -0
- data/app/views/docs/interdasting/_hash_param.slim +7 -0
- data/app/views/docs/interdasting/_version.slim +7 -0
- data/app/views/docs/interdasting/index.slim +3 -0
- data/app/views/docs/interdasting/show.markdown.erb +3 -0
- data/app/views/docs/interdasting/show.slim +4 -0
- data/app/views/layouts/interdasting/_modal.slim +12 -0
- data/app/views/layouts/interdasting/_navigation.slim +10 -0
- data/app/views/layouts/interdasting/application.slim +9 -0
- data/config/routes.rb +5 -0
- data/lib/interdasting.rb +30 -0
- data/lib/interdasting/documentation.rb +46 -0
- data/lib/interdasting/documentation/action.rb +97 -0
- data/lib/interdasting/documentation/controller.rb +57 -0
- data/lib/interdasting/engine.rb +12 -0
- data/lib/interdasting/parser.rb +105 -0
- data/lib/interdasting/router.rb +86 -0
- data/lib/interdasting/version.rb +3 -0
- data/lib/tasks/interdasting_tasks.rake +85 -0
- metadata +270 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6ba6bc08627a70924d0a296b836229b2bd9e8956
|
4
|
+
data.tar.gz: 7a4b2661e3e53b9894f4d7829a7ecb7ae0d20e61
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7eedceccdd1c12f8fd99e846fc33c22b394f2e187fa7de900d8ced645f60399bcf72176440c87e5c6fa65da68891b30b8a81982a3291cfbca5f57183a2b5479d
|
7
|
+
data.tar.gz: 73b9763b4c8b1d2e08118af238aeeb405a37be75c3857af85a764e29caadc5824e87b94508618663826940808d8157ef5996c16f032c40c239493e03dcd4745d
|
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,23 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Interdasting'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/test_app/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
@@ -0,0 +1,198 @@
|
|
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
|
+
$modal.find('.response-body').removeClass('hidden');
|
26
|
+
addSpinner($response);
|
27
|
+
$.ajax(
|
28
|
+
buildRequestParams($modal.find('.modal-body'), $triggerButton.data('url'), $triggerButton.data('request-method'))
|
29
|
+
).done(function(data, textStatus, jqXHR) {
|
30
|
+
response = jqXHR.responseText
|
31
|
+
$response.html('');
|
32
|
+
$response.text(response);
|
33
|
+
$(window).trigger('resize');
|
34
|
+
});
|
35
|
+
});
|
36
|
+
}).on('hidden.bs.modal', function (e) {
|
37
|
+
var $modal = $(this);
|
38
|
+
$modal.find('h4.modal-title').text('Try it');
|
39
|
+
$modal.find('.modal-body').html('');
|
40
|
+
})
|
41
|
+
|
42
|
+
function buildRequestParams($object, url, method) {
|
43
|
+
var $inputs = $object.find('input[data-key]');
|
44
|
+
var $requestBody = $object.find('textarea');
|
45
|
+
var data = null;
|
46
|
+
var processData = true;
|
47
|
+
|
48
|
+
if ($inputs.length !== 0) {
|
49
|
+
data = {}
|
50
|
+
$inputs.each(function(i, $input) {
|
51
|
+
$input = $($input);
|
52
|
+
if (url.indexOf('{' + $input.data('key') + '}')) {
|
53
|
+
url = url.replace('{' + $input.data('key') + '}', $input.val())
|
54
|
+
} else {
|
55
|
+
data[$input.data('key')] = $input.val();
|
56
|
+
}
|
57
|
+
});
|
58
|
+
}
|
59
|
+
if ($requestBody.length !== 0) {
|
60
|
+
processData = false;
|
61
|
+
data = $requestBody.val();
|
62
|
+
}
|
63
|
+
|
64
|
+
return {
|
65
|
+
url: url,
|
66
|
+
type: method,
|
67
|
+
processData: processData,
|
68
|
+
data: data
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
function saveParams($object, $saveToObject) {
|
73
|
+
var $inputs = $object.find('input[data-key]');
|
74
|
+
var $requestBody = $object.find('textarea');
|
75
|
+
|
76
|
+
if ($inputs.length !== 0) {
|
77
|
+
params = {};
|
78
|
+
$inputs.each(function(i, $input) {
|
79
|
+
$input = $($input);
|
80
|
+
params[$input.data('key')] = $input.val();
|
81
|
+
});
|
82
|
+
$saveToObject.data('saved_params', params);
|
83
|
+
}
|
84
|
+
|
85
|
+
if ($requestBody.length !== 0) {
|
86
|
+
$saveToObject.data('saved_text', $requestBody.val());
|
87
|
+
}
|
88
|
+
|
89
|
+
return true;
|
90
|
+
}
|
91
|
+
|
92
|
+
function addSpinner($object) {
|
93
|
+
var message = '<center>'+
|
94
|
+
'<span class="glyphicon glyphicon-refresh gly-spin"></span>'+
|
95
|
+
' Waiting for response...'+
|
96
|
+
'</center>';
|
97
|
+
$object.html(message);
|
98
|
+
}
|
99
|
+
|
100
|
+
function contentForModal(url, method, params, savedParams, savedText) {
|
101
|
+
var content = ''
|
102
|
+
content += '<h3>Request body</h3>'
|
103
|
+
if (method === 'GET' && params) {
|
104
|
+
content += paramsInputTable(params, savedParams)
|
105
|
+
} else {
|
106
|
+
var regex = /\{[^\s]+\}/;
|
107
|
+
var match = regex.exec(url);
|
108
|
+
if (match && match.length !== 0) {
|
109
|
+
tempParams = {}
|
110
|
+
$.each(match, function(i, m){ tempParams[m.replace(/[\{\}]/g,'')] = i });
|
111
|
+
content += paramsInputTable(tempParams, savedParams)
|
112
|
+
}
|
113
|
+
var saved = ''
|
114
|
+
if (savedText) saved = savedText;
|
115
|
+
content += '<textarea class="form-control" rows="6" cols="90">' + saved + '</textarea>';
|
116
|
+
}
|
117
|
+
if (method !== 'GET' && params) {
|
118
|
+
content += '<h4>Expected params</h4>'
|
119
|
+
content += paramsTable(params)
|
120
|
+
}
|
121
|
+
content += '<div class="response-body hidden">'
|
122
|
+
content += '<hr>';
|
123
|
+
content += '<h3>Response</h3>'
|
124
|
+
content += '<pre><code class="response"></code></pre>'
|
125
|
+
content += '</div>'
|
126
|
+
|
127
|
+
return content;
|
128
|
+
}
|
129
|
+
|
130
|
+
function paramsInputTable(params, savedParams) {
|
131
|
+
content = '<table class="table table-striped">';
|
132
|
+
content += '<thead>';
|
133
|
+
content += '<tr>'+
|
134
|
+
'<th>Param</th>'+
|
135
|
+
'<th>Value</th>'+
|
136
|
+
'</tr>';
|
137
|
+
content += '</thead>';
|
138
|
+
$.each(params, function(k, v) {
|
139
|
+
content += paramsInputTableRow(k, v, null, savedParams);
|
140
|
+
});
|
141
|
+
content += '</table>';
|
142
|
+
return content
|
143
|
+
}
|
144
|
+
|
145
|
+
function paramsInputTableRow(k, v, wrapper, savedParams) {
|
146
|
+
var content = '';
|
147
|
+
var saved = '';
|
148
|
+
if (wrapper) k = wrapper + '[' + k + ']';
|
149
|
+
if (savedParams && savedParams[k]) saved = savedParams[k];
|
150
|
+
if (typeof v === 'object') {
|
151
|
+
$.each(v, function(kk, vv) {
|
152
|
+
content += paramsInputTableRow(kk, vv, k, savedParams);
|
153
|
+
});
|
154
|
+
} else {
|
155
|
+
content += '<tr>'+
|
156
|
+
'<td>' + k + '</td>'+
|
157
|
+
'<td><input type="text" class="form-control" value="' + saved + '" data-key="' + k + '"></td>'+
|
158
|
+
'</tr>';
|
159
|
+
}
|
160
|
+
return content;
|
161
|
+
}
|
162
|
+
|
163
|
+
function paramsTable(params) {
|
164
|
+
content = '<table class="table table-striped">';
|
165
|
+
content += '<thead>';
|
166
|
+
content += '<tr>'+
|
167
|
+
'<th>Name</th>'+
|
168
|
+
'<th>Type</th>'+
|
169
|
+
'</tr>';
|
170
|
+
content += '</thead>';
|
171
|
+
$.each(params, function(k, v){
|
172
|
+
content += paramsTableRow(k, v, null);
|
173
|
+
});
|
174
|
+
content += '</table>';
|
175
|
+
return content
|
176
|
+
}
|
177
|
+
|
178
|
+
function paramsTableRow(k, v, wrapper) {
|
179
|
+
var content = '';
|
180
|
+
if (wrapper) k = wrapper + '[' + k + ']';
|
181
|
+
if (typeof v === 'object') {
|
182
|
+
$.each(v, function(kk, vv) {
|
183
|
+
content += paramsTableRow(kk, vv, k);
|
184
|
+
});
|
185
|
+
} else {
|
186
|
+
content += '<tr>'+
|
187
|
+
'<td>' + k + '</td>'+
|
188
|
+
'<td>' + v + '</td>'+
|
189
|
+
'</tr>';
|
190
|
+
}
|
191
|
+
return content;
|
192
|
+
}
|
193
|
+
|
194
|
+
function indentResponse(response) {
|
195
|
+
// TODO: code to indent the response depending on if it's a JSON or XML response
|
196
|
+
return response;
|
197
|
+
}
|
198
|
+
});
|
@@ -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 Interdasting
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
def index
|
4
|
+
@docs = Interdasting.documentation
|
5
|
+
render 'docs/interdasting/index'
|
6
|
+
end
|
7
|
+
|
8
|
+
def show
|
9
|
+
@doc = Interdasting.documentation_for_version(params[:version])
|
10
|
+
render 'docs/interdasting/show'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Interdasting
|
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/interdasting/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/interdasting/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?(interdasting)
|
2
|
+
.navbar.navbar-default.navbar-fixed-top
|
3
|
+
.container-fluid
|
4
|
+
.navbar-header
|
5
|
+
= link_to 'Documentation', interdasting.root_path, class: 'navbar-brand'
|
6
|
+
.collapse.navbar-collapse
|
7
|
+
ul.nav.navbar-nav
|
8
|
+
li = link_to 'All versions', interdasting.root_path
|
9
|
+
- Interdasting::Router.versions.each do |v|
|
10
|
+
li = link_to v.to_s, interdasting.version_path(version: v)
|
data/config/routes.rb
ADDED
data/lib/interdasting.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'pry'
|
2
|
+
require 'slim'
|
3
|
+
require 'indentation-parser'
|
4
|
+
require 'interdasting/engine'
|
5
|
+
require 'interdasting/router'
|
6
|
+
require 'interdasting/parser'
|
7
|
+
require 'interdasting/documentation'
|
8
|
+
|
9
|
+
module Interdasting
|
10
|
+
def self.documentation
|
11
|
+
Router.api_full.map do |version, controller|
|
12
|
+
Documentation.new(version, controller)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.documentation_for_version(version)
|
17
|
+
Documentation.new(version, Router.api_full[version])
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.documentation_for_files(files, version_name = 'Unknown')
|
21
|
+
fake_controlers = files.map do |file|
|
22
|
+
fake_controller = {
|
23
|
+
path: file,
|
24
|
+
actions: Hash[Parser.method_comments(file).keys.map { |m, _c| [m, []] }]
|
25
|
+
}
|
26
|
+
[File.basename(file, '.rb'), fake_controller]
|
27
|
+
end
|
28
|
+
Documentation.new(version_name, Hash[fake_controlers])
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'interdasting/documentation/controller'
|
2
|
+
require 'interdasting/documentation/action'
|
3
|
+
|
4
|
+
module Interdasting
|
5
|
+
class Documentation
|
6
|
+
attr_reader :version
|
7
|
+
attr_reader :controllers
|
8
|
+
|
9
|
+
def initialize(version, controllers_hash)
|
10
|
+
@version = version
|
11
|
+
@controllers = []
|
12
|
+
@controllers_in = controllers_hash
|
13
|
+
generate
|
14
|
+
end
|
15
|
+
|
16
|
+
def should_update?
|
17
|
+
should_update = false
|
18
|
+
controllers.each { |c| should_update ||= c.should_update? }
|
19
|
+
should_update
|
20
|
+
end
|
21
|
+
|
22
|
+
def update
|
23
|
+
controllers.each(&:update)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def update!
|
28
|
+
controllers.each(&:update!)
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def generate
|
35
|
+
build_controllers
|
36
|
+
update
|
37
|
+
end
|
38
|
+
|
39
|
+
def build_controllers
|
40
|
+
@controllers = []
|
41
|
+
@controllers_in.each do |n, v|
|
42
|
+
@controllers << Controller.new(n, v[:path], v[:actions], self)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Interdasting
|
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
|
+
(@doc[method] && @doc[method]['DOC']) || @doc['DOC']
|
26
|
+
end
|
27
|
+
|
28
|
+
def params(method = default_method)
|
29
|
+
(@doc[method] && @doc[method]['PARAMS']) || @doc['PARAMS'] ||
|
30
|
+
@params
|
31
|
+
end
|
32
|
+
|
33
|
+
def default_method
|
34
|
+
methods.first || 'GET'
|
35
|
+
end
|
36
|
+
|
37
|
+
def methods
|
38
|
+
@methods.presence ||
|
39
|
+
@doc.keys.select { |m| Parser.http_keywords.include?(m) }
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def generate
|
45
|
+
return @doc = {} unless @comments.present?
|
46
|
+
@doc = Interdasting::Parser.parse_comments(@comments).value
|
47
|
+
end
|
48
|
+
|
49
|
+
def _routes
|
50
|
+
Interdasting::Router.app_routes
|
51
|
+
end
|
52
|
+
|
53
|
+
def sanitize_methods(methods)
|
54
|
+
return unless methods
|
55
|
+
methods.map do |m|
|
56
|
+
if m.is_a?(String)
|
57
|
+
m
|
58
|
+
else
|
59
|
+
m.to_s.sub('(?-mix:^', '').sub('$)', '').split('|')
|
60
|
+
end
|
61
|
+
end.flatten
|
62
|
+
end
|
63
|
+
|
64
|
+
def router_url(method = default_method)
|
65
|
+
route = _routes.url_for(url_params(method))
|
66
|
+
route = route.split('?').first unless method == 'GET'
|
67
|
+
CGI.unescape(route)
|
68
|
+
rescue ActionController::UrlGenerationError
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
def url_params(method = default_method)
|
73
|
+
hash = {}
|
74
|
+
hash = deflated_url_params(params(method)) if @params
|
75
|
+
hash.merge(
|
76
|
+
controller: controller.full_name.downcase,
|
77
|
+
action: name,
|
78
|
+
version: controller.documentation.version,
|
79
|
+
only_path: true
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
def deflated_url_params(hash, wrapper = nil)
|
84
|
+
nh = {}
|
85
|
+
hash.each do |k, v|
|
86
|
+
new_v = wrapper ? "#{wrapper}[#{k}]" : k
|
87
|
+
if v.is_a?(Hash)
|
88
|
+
nh[k] = deflated_url_params(v, k)
|
89
|
+
else
|
90
|
+
nh[k] = "{#{new_v}}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
nh.symbolize_keys
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Interdasting
|
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 = Interdasting::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
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Interdasting
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace Interdasting
|
4
|
+
require 'jquery-rails'
|
5
|
+
require 'bootstrap-sass'
|
6
|
+
|
7
|
+
config.generators do |g|
|
8
|
+
g.test_framework :rspec
|
9
|
+
g.fixture_replacement :factory_girl, dir: 'spec/factories'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Interdasting
|
2
|
+
module Parser
|
3
|
+
class << self
|
4
|
+
def comments_for_method(method_name, file_path)
|
5
|
+
method_comments(file_path)[method_name.to_s]
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_comments(file_path)
|
9
|
+
comments = {}
|
10
|
+
temp_comment = []
|
11
|
+
File.read(file_path).each_line do |line|
|
12
|
+
if extract_method_comment(line, comments, temp_comment)
|
13
|
+
temp_comment = []
|
14
|
+
end
|
15
|
+
end
|
16
|
+
clean_comments(comments)
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse_comments(comments)
|
20
|
+
indentation_parser.read(comments, {})
|
21
|
+
end
|
22
|
+
|
23
|
+
def keywords
|
24
|
+
http_keywords + parser_keywords
|
25
|
+
end
|
26
|
+
|
27
|
+
def http_keywords
|
28
|
+
%w(GET POST PUT PATCH DELETE)
|
29
|
+
end
|
30
|
+
|
31
|
+
def parser_keywords
|
32
|
+
string_keywords + hash_keywords
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def string_keywords
|
38
|
+
%w(DOC URL)
|
39
|
+
end
|
40
|
+
|
41
|
+
def hash_keywords
|
42
|
+
%w(PARAMS)
|
43
|
+
end
|
44
|
+
|
45
|
+
def indentation_parser
|
46
|
+
IndentationParser.new do |p|
|
47
|
+
indentation_parser_default(p)
|
48
|
+
indentation_parser_leafs(p)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def indentation_parser_default(p)
|
53
|
+
p.default do |parent, source|
|
54
|
+
parent ||= {}
|
55
|
+
words = source.split
|
56
|
+
keyword, key = words.first.upcase, words.first
|
57
|
+
if words.count == 1 && keywords.include?(keyword)
|
58
|
+
parent[keyword] = string_keywords.include?(keyword) ? '' : {}
|
59
|
+
elsif words.count == 1 && parent.is_a?(Hash)
|
60
|
+
parent[key] = {}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def indentation_parser_leafs(p)
|
66
|
+
p.on_leaf do |parent, source|
|
67
|
+
case parent
|
68
|
+
when String
|
69
|
+
parent << ' ' if parent.length != 0
|
70
|
+
parent << source.try(:strip) || ''
|
71
|
+
when Hash
|
72
|
+
k, v = source.split(':', 2)
|
73
|
+
parent[k] = v ? v.try(:strip) : {}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def extract_method_comment(line, comments = {}, temp_comment = [])
|
79
|
+
return true unless valid_line?(line)
|
80
|
+
if line =~ /^\s*def\s+\w+$/
|
81
|
+
comments[method_name(line)] = temp_comment.join("\n")
|
82
|
+
true
|
83
|
+
else
|
84
|
+
temp_comment << line
|
85
|
+
false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def valid_line?(line)
|
90
|
+
line =~ /^\s*#.*$/ || line =~ /^\s*def\s+\w+$/ || line =~ /^\s+$/
|
91
|
+
end
|
92
|
+
|
93
|
+
def method_name(line)
|
94
|
+
line.match(/^\s*def\s+\w+$/).to_s.split(' ').last
|
95
|
+
end
|
96
|
+
|
97
|
+
def clean_comments(comments)
|
98
|
+
comments.each do |k, v|
|
99
|
+
comments[k] = v.gsub(/^\s*#\s?/, '').gsub(/\n+/, "\n")
|
100
|
+
end
|
101
|
+
comments
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Interdasting
|
2
|
+
module Router
|
3
|
+
class << self
|
4
|
+
def api_full
|
5
|
+
result = {}
|
6
|
+
versions.each { |v| result[v] = {} }
|
7
|
+
result.each { |k, v| fill_controllers_hash_for_version(k, v) }
|
8
|
+
result
|
9
|
+
end
|
10
|
+
|
11
|
+
def api_controller_paths(controllers = api_controllers)
|
12
|
+
cp = controllers.map do |c|
|
13
|
+
c.instance_methods(false).map do |m|
|
14
|
+
c.instance_method(m).source_location.first
|
15
|
+
end
|
16
|
+
end
|
17
|
+
cp.flatten.uniq.compact
|
18
|
+
end
|
19
|
+
|
20
|
+
def api_controllers(names = api_controller_names)
|
21
|
+
names.map do |cn|
|
22
|
+
cn += '_controller'
|
23
|
+
cn.classify.constantize
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def api_controller_names
|
28
|
+
ar = routes.named_routes.select { |_k, v| v.defaults[:rp_prefix] }
|
29
|
+
ar.values.map { |r| r.defaults[:controller] }.uniq
|
30
|
+
end
|
31
|
+
|
32
|
+
def routes_for_version(version)
|
33
|
+
routes.to_a.select { |v| v && v.defaults[:version] == version }
|
34
|
+
end
|
35
|
+
|
36
|
+
def versions
|
37
|
+
routes.to_a.map { |r| r && r.defaults[:version] }.uniq.compact
|
38
|
+
end
|
39
|
+
|
40
|
+
def routes
|
41
|
+
app_routes.routes
|
42
|
+
end
|
43
|
+
|
44
|
+
def app_routes
|
45
|
+
Rails.application.class.routes
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def fill_controllers_hash_for_version(version, hash)
|
51
|
+
routes = routes_for_version(version)
|
52
|
+
routes.each do |r|
|
53
|
+
route_controller(hash, r)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def route_controller(ch, r)
|
58
|
+
cn = r.defaults[:controller]
|
59
|
+
ch[cn] ||= {}
|
60
|
+
ch[cn][:path] ||= api_controller_paths(api_controllers([cn])).first
|
61
|
+
ch[cn][:actions] ||= {}
|
62
|
+
route_action(ch[cn][:actions], r)
|
63
|
+
end
|
64
|
+
|
65
|
+
def route_action(hash, r)
|
66
|
+
ah = hash[r.defaults[:action]] ||= {}
|
67
|
+
ah[:params] = route_params(r)
|
68
|
+
route_methods(ah, r)
|
69
|
+
end
|
70
|
+
|
71
|
+
def route_params(r)
|
72
|
+
Hash[
|
73
|
+
r.required_parts.map do |name|
|
74
|
+
type = r.constraints[name.to_sym] || '???'
|
75
|
+
[name, type]
|
76
|
+
end
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
def route_methods(hash, r)
|
81
|
+
hash[:methods] ||= []
|
82
|
+
hash[:methods] << r.constraints[:request_method]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
namespace :interdasting do
|
2
|
+
desc 'Generates static HTML documentation files'
|
3
|
+
generator_args = [:version_name, :input_files, :output_folder]
|
4
|
+
task :generate, generator_args => :environment do |_task, args|
|
5
|
+
version, input, output = sanitize_generator_input(args)
|
6
|
+
fail('A version name has to be provided') unless version
|
7
|
+
fail('At leas one input file has to be provided') unless input
|
8
|
+
|
9
|
+
doc = Interdasting.documentation_for_files(input, version)
|
10
|
+
|
11
|
+
template_folder = generator_template_folder
|
12
|
+
layout_path = template_folder + '/layouts/interdasting/application.slim'
|
13
|
+
template_path = template_folder + '/docs/interdasting/show.slim'
|
14
|
+
|
15
|
+
prepare_generator_output(output, version, 'html')
|
16
|
+
|
17
|
+
view_builder = generator_view_builder(template_folder)
|
18
|
+
view_builder.instance_variable_set(:@doc, doc)
|
19
|
+
layout = Slim::Template.new { File.open(layout_path, 'r').read }
|
20
|
+
view = Slim::Template.new { File.open(template_path, 'r').read }
|
21
|
+
html = layout.render(view_builder) do
|
22
|
+
view.render(view_builder).html_safe
|
23
|
+
end
|
24
|
+
File.open(output, 'w+') do |file|
|
25
|
+
file.puts(html)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
task :gen, generator_args => :generate
|
29
|
+
|
30
|
+
desc 'Generates static MARKDOWN documentation files'
|
31
|
+
md_generator_args = generator_args
|
32
|
+
task :generate_markdown, md_generator_args => :environment do |_task, args|
|
33
|
+
version, input, output = sanitize_generator_input(args)
|
34
|
+
|
35
|
+
doc = Interdasting.documentation_for_files(input, version)
|
36
|
+
|
37
|
+
template_folder = generator_template_folder
|
38
|
+
template_path = template_folder + '/docs/interdasting/show.markdown.erb'
|
39
|
+
|
40
|
+
prepare_generator_output(output, version, 'markdown')
|
41
|
+
|
42
|
+
view_builder = generator_view_builder(template_folder)
|
43
|
+
view_builder.instance_variable_set(:@doc, doc)
|
44
|
+
view = ERB.new(File.open(template_path, 'r').read)
|
45
|
+
html = view.result(view_builder.instance_eval { binding })
|
46
|
+
File.open(output, 'w+') do |file|
|
47
|
+
file.puts(html)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
task :generate_md, md_generator_args => :generate_markdown
|
51
|
+
task :gen_md, md_generator_args => :generate_markdown
|
52
|
+
|
53
|
+
###############
|
54
|
+
### HELPERS ###
|
55
|
+
###############
|
56
|
+
|
57
|
+
def sanitize_generator_input(args)
|
58
|
+
version = args[:version_name].presence
|
59
|
+
# TODO: Potential bug with pathnames containing spaces
|
60
|
+
input = args[:input_files] && args[:input_files].split.presence
|
61
|
+
output = args[:output_folder].presence ||
|
62
|
+
Rails.root.join('public', 'system', 'documentation').to_s
|
63
|
+
fail('A version name has to be provided') unless version
|
64
|
+
fail('At leas one input file has to be provided') unless input
|
65
|
+
[version, input, output]
|
66
|
+
end
|
67
|
+
|
68
|
+
def generator_template_folder
|
69
|
+
File.expand_path('../../../app/views', __FILE__)
|
70
|
+
end
|
71
|
+
|
72
|
+
def prepare_generator_output(output, name, ext)
|
73
|
+
FileUtils.mkdir_p(output)
|
74
|
+
output = output[-1] == '/' ? output : output << '/'
|
75
|
+
output << "#{name}.#{ext}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def generator_view_builder(template_folder)
|
79
|
+
lookup_context = ActionView::LookupContext.new(template_folder)
|
80
|
+
view_builder = ActionView::Base.new(lookup_context)
|
81
|
+
view_builder.extend ActionView::Helpers
|
82
|
+
view_builder.extend Interdasting::ApplicationHelper
|
83
|
+
view_builder
|
84
|
+
end
|
85
|
+
end
|
metadata
ADDED
@@ -0,0 +1,270 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: interdasting
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stanko Krtalić Rusendić
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: slim-rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: jquery-rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sass-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bootstrap-sass
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.3'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: indentation-parser
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec-rails
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.2'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.2'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: factory_girl_rails
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '4.5'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '4.5'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rocket_pants
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.10'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '1.10'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: pry
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.10'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.10'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: pry-rails
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.3'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.3'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: better_errors
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '2.1'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '2.1'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: binding_of_caller
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0.7'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0.7'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: sqlite3
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '1.3'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '1.3'
|
209
|
+
description: Unintrusive interactive API documentation generator for rails apps
|
210
|
+
email:
|
211
|
+
- stanko.krtalic@gmial.com
|
212
|
+
executables: []
|
213
|
+
extensions: []
|
214
|
+
extra_rdoc_files: []
|
215
|
+
files:
|
216
|
+
- MIT-LICENSE
|
217
|
+
- Rakefile
|
218
|
+
- app/assets/javascripts/interdasting/application.js
|
219
|
+
- app/assets/stylesheets/interdasting/application.scss
|
220
|
+
- app/controllers/interdasting/application_controller.rb
|
221
|
+
- app/helpers/interdasting/application_helper.rb
|
222
|
+
- app/views/docs/interdasting/_action.markdown.erb
|
223
|
+
- app/views/docs/interdasting/_action.slim
|
224
|
+
- app/views/docs/interdasting/_controller.markdown.erb
|
225
|
+
- app/views/docs/interdasting/_controller.slim
|
226
|
+
- app/views/docs/interdasting/_documentation.markdown.erb
|
227
|
+
- app/views/docs/interdasting/_documentation.slim
|
228
|
+
- app/views/docs/interdasting/_hash_param.slim
|
229
|
+
- app/views/docs/interdasting/_version.slim
|
230
|
+
- app/views/docs/interdasting/index.slim
|
231
|
+
- app/views/docs/interdasting/show.markdown.erb
|
232
|
+
- app/views/docs/interdasting/show.slim
|
233
|
+
- app/views/layouts/interdasting/_modal.slim
|
234
|
+
- app/views/layouts/interdasting/_navigation.slim
|
235
|
+
- app/views/layouts/interdasting/application.slim
|
236
|
+
- config/routes.rb
|
237
|
+
- lib/interdasting.rb
|
238
|
+
- lib/interdasting/documentation.rb
|
239
|
+
- lib/interdasting/documentation/action.rb
|
240
|
+
- lib/interdasting/documentation/controller.rb
|
241
|
+
- lib/interdasting/engine.rb
|
242
|
+
- lib/interdasting/parser.rb
|
243
|
+
- lib/interdasting/router.rb
|
244
|
+
- lib/interdasting/version.rb
|
245
|
+
- lib/tasks/interdasting_tasks.rake
|
246
|
+
homepage: http://github.com/stankec
|
247
|
+
licenses:
|
248
|
+
- MIT
|
249
|
+
metadata: {}
|
250
|
+
post_install_message:
|
251
|
+
rdoc_options: []
|
252
|
+
require_paths:
|
253
|
+
- lib
|
254
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
255
|
+
requirements:
|
256
|
+
- - ">="
|
257
|
+
- !ruby/object:Gem::Version
|
258
|
+
version: '0'
|
259
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
260
|
+
requirements:
|
261
|
+
- - ">="
|
262
|
+
- !ruby/object:Gem::Version
|
263
|
+
version: '0'
|
264
|
+
requirements: []
|
265
|
+
rubyforge_project:
|
266
|
+
rubygems_version: 2.2.2
|
267
|
+
signing_key:
|
268
|
+
specification_version: 4
|
269
|
+
summary: Interactive API documentation for rails apps
|
270
|
+
test_files: []
|