api_doc_generation 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/api_doc_generation.rb +67 -35
- data/lib/api_doc_generation/version.rb +1 -1
- data/lib/api_doc_generation/view_helper.rb +51 -0
- data/lib/rake/tasks/api_doc.rake +14 -2
- data/templates/doc_detailed.html.erb +208 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5dd65a3e0535829684cdead694989b6925fc4dc8
|
4
|
+
data.tar.gz: bed4b14919575ffd572bf54cb505ecad836a5c9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 049c508ad6dfacf37e953a0150cd805046edea284e31c71636de103aa4172b56f456412c1764588cb9bc73a3b51aece45948c24281a9939c28c000928ff872bb
|
7
|
+
data.tar.gz: 550ae99b642a1bc4558c0e72f13a14eff8ab04197a729110c822c5ff21874fffcfb792a45d0ee92c9b24a76aac361a3c6161a22e164ae8cea36fb46f1d351cbf
|
data/lib/api_doc_generation.rb
CHANGED
@@ -10,31 +10,39 @@ end
|
|
10
10
|
|
11
11
|
|
12
12
|
module ApiDocGeneration; class Generation
|
13
|
-
def initialize(codes_path = nil
|
13
|
+
def initialize(codes_path = nil)
|
14
14
|
codes_path ||= File.expand_path('app/controllers/api', Rails.root)
|
15
|
-
|
16
|
-
controller_documents = []
|
15
|
+
@controller_documents = []
|
17
16
|
|
18
17
|
each_api_controllers_file(codes_path) do |path|
|
19
18
|
controller_path = path.split("app/controllers").last
|
20
19
|
class_name = controller_path.gsub('.rb', '').classify
|
21
20
|
klass = class_name.safe_constantize
|
22
21
|
|
23
|
-
controller_documents << generate_controller(path, klass)
|
22
|
+
@controller_documents << generate_controller(path, klass)
|
24
23
|
end
|
25
|
-
|
26
|
-
generate_html_string(controller_documents)
|
27
24
|
end
|
28
25
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
|
27
|
+
def generate_html_string
|
28
|
+
template = ERB.new(
|
29
|
+
File.read(File.expand_path('../../templates/doc.html.erb', __FILE__))
|
30
|
+
)
|
31
|
+
|
32
|
+
ViewHelper.render(template, {
|
33
|
+
:documents => @controller_documents
|
34
|
+
})
|
33
35
|
end
|
34
36
|
|
35
37
|
|
36
|
-
def
|
37
|
-
|
38
|
+
def generate_detailed_html_string
|
39
|
+
template = ERB.new(
|
40
|
+
File.read(File.expand_path('../../templates/doc_detailed.html.erb', __FILE__))
|
41
|
+
)
|
42
|
+
|
43
|
+
ViewHelper.render(template, {
|
44
|
+
:documents => @controller_documents
|
45
|
+
})
|
38
46
|
end
|
39
47
|
|
40
48
|
|
@@ -73,12 +81,14 @@ module ApiDocGeneration; class Generation
|
|
73
81
|
{
|
74
82
|
:path => path,
|
75
83
|
:klass => klass.to_s,
|
76
|
-
:actions => actions
|
84
|
+
:actions => actions,
|
85
|
+
:about => get_controller_about(filelines, klass.to_s)
|
77
86
|
}
|
78
87
|
end
|
79
88
|
|
80
89
|
|
81
90
|
|
91
|
+
# {name: 'xx', desc: 'yy', Params: [{level: 1, }]}
|
82
92
|
def generate_action(klass, action, filelines)
|
83
93
|
document = {:name => action.to_s}
|
84
94
|
method = klass.instance_method action
|
@@ -97,21 +107,7 @@ module ApiDocGeneration; class Generation
|
|
97
107
|
line.gsub!(/\s*\#/, '')
|
98
108
|
next if line =~ /^\s*$/
|
99
109
|
|
100
|
-
|
101
|
-
level = m[:level].length / 2
|
102
|
-
desc = m[:desc].gsub(/^\s*|\s*$/, '')
|
103
|
-
line.gsub!(/^\s*|\:?\s*$/, '')
|
104
|
-
|
105
|
-
if level == 0
|
106
|
-
if tmp.length == 0 && m[:val] && m[:val].length > 0
|
107
|
-
document[m[:key]] = m[:val]
|
108
|
-
else
|
109
|
-
document[m[:key] + (m[:val] || '')] = tmp.reverse
|
110
|
-
end
|
111
|
-
tmp = []
|
112
|
-
else
|
113
|
-
tmp << {:level => level, :desc => desc}
|
114
|
-
end
|
110
|
+
format_line(line, tmp, document)
|
115
111
|
|
116
112
|
last_line = line
|
117
113
|
end
|
@@ -143,16 +139,52 @@ module ApiDocGeneration; class Generation
|
|
143
139
|
end
|
144
140
|
|
145
141
|
|
142
|
+
def format_line(line, tmp, document)
|
143
|
+
m = line.match(/(?<level>\s*)(?<desc>(?<key>.*?)(\:(?<val>.*?))?)$/)
|
144
|
+
level = m[:level].length / 2
|
145
|
+
desc = m[:desc].gsub(/^\s*|\s*$/, '')
|
146
|
+
line.gsub!(/^\s*|\:?\s*$/, '')
|
146
147
|
|
148
|
+
if level == 0
|
149
|
+
if tmp.length == 0 && m[:val] && m[:val].length > 0
|
150
|
+
document[m[:key]] = m[:val]
|
151
|
+
else
|
152
|
+
document[m[:key] + (m[:val] || '')] = tmp.reverse.each_with_object([]) do |p, result|
|
153
|
+
if p[:level] >= 2 && result.last
|
154
|
+
result.last[:children] ||= []
|
155
|
+
result.last[:children] << p
|
156
|
+
else
|
157
|
+
result << p
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
tmp.clear
|
162
|
+
else
|
163
|
+
m = desc.match(/(?<name>\w+)\:?\s*((\[(?<type>.*?)\]\s*)?(?<val>.*))?$/)
|
164
|
+
p = {:level => level, :desc => desc}
|
165
|
+
|
166
|
+
p.merge!({
|
167
|
+
:name => m[:name],
|
168
|
+
:type => m[:type],
|
169
|
+
:val => m[:val]
|
170
|
+
}) if m
|
171
|
+
|
172
|
+
tmp << p
|
173
|
+
end
|
174
|
+
end
|
147
175
|
|
148
|
-
def generate_html_string(controller_documents)
|
149
|
-
template = ERB.new(
|
150
|
-
File.read(File.expand_path('../../templates/doc.html.erb', __FILE__))
|
151
|
-
)
|
152
176
|
|
153
|
-
|
154
|
-
|
155
|
-
|
177
|
+
|
178
|
+
def get_controller_about(filelines, class_name)
|
179
|
+
pre_line = ''
|
180
|
+
|
181
|
+
filelines.each do |line|
|
182
|
+
break if line =~ /class\s#{Regexp.escape(class_name)}/
|
183
|
+
pre_line = line
|
184
|
+
end
|
185
|
+
|
186
|
+
pre_line.gsub(/^\s*#\s*/, '')
|
156
187
|
end
|
157
188
|
|
189
|
+
|
158
190
|
end; end
|
@@ -24,4 +24,55 @@ module ApiDocGeneration; class ViewHelper
|
|
24
24
|
def action_identifer(controller_name, action_name)
|
25
25
|
"action-#{Digest::MD5.hexdigest(controller_name)}-#{action_name}"
|
26
26
|
end
|
27
|
+
|
28
|
+
|
29
|
+
def controller_identifer(controller_name)
|
30
|
+
"controller-#{Digest::MD5.hexdigest(controller_name)}"
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def format_param(param)
|
35
|
+
return unless param[:val].to_s =~ /^\s*$/
|
36
|
+
|
37
|
+
case param[:name]
|
38
|
+
when 'app_uname'
|
39
|
+
param[:type] = 'String'
|
40
|
+
param[:val] = 'app的唯一标识名,表明调用此api是在哪个app下'
|
41
|
+
when 'access_token'
|
42
|
+
param[:type] = 'String'
|
43
|
+
param[:val] = '请求的唯一标识,用于识别用户,用户登陆返回或是使用refresh_token换取'
|
44
|
+
when 'refresh_token'
|
45
|
+
param[:type] = 'String'
|
46
|
+
param[:val] = '用户登陆时返回,使用此token来取得新的access_token'
|
47
|
+
when 'page'
|
48
|
+
param[:type] = 'Integer'
|
49
|
+
param[:val] = '返回所有数据中的第几页'
|
50
|
+
when 'perpage'
|
51
|
+
param[:type] = 'Integer'
|
52
|
+
param[:val] = '返回数据每页多少条'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def format_error_param(param)
|
58
|
+
return unless param[:val].to_s =~ /^\s*$/
|
59
|
+
|
60
|
+
case param[:name]
|
61
|
+
when 'current_page'
|
62
|
+
param[:type] = 'Integer'
|
63
|
+
param[:val] = '当前返回数据是第几页'
|
64
|
+
when 'perpage'
|
65
|
+
param[:type] = 'Integer'
|
66
|
+
param[:val] = '每页返回的数据量'
|
67
|
+
when 'count'
|
68
|
+
param[:type] = 'Integer'
|
69
|
+
param[:val] = '数据总数量'
|
70
|
+
when 'items'
|
71
|
+
param[:type] = 'Array'
|
72
|
+
param[:val] = '数组中存放当前页的数据'
|
73
|
+
when 'total_pages'
|
74
|
+
param[:type] = 'Integer'
|
75
|
+
param[:val] = '数据的总页数'
|
76
|
+
end
|
77
|
+
end
|
27
78
|
end; end
|
data/lib/rake/tasks/api_doc.rake
CHANGED
@@ -3,10 +3,22 @@ namespace :doc do
|
|
3
3
|
task :api => :environment do
|
4
4
|
require 'api_doc_generation'
|
5
5
|
|
6
|
+
out_format = ENV['OUT_FORMAT'] || 'detailed_html'
|
6
7
|
codes_path = ENV['CODES_PATH'] || File.expand_path('app/controllers/api', Rails.root)
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
puts out_format
|
10
|
+
|
11
|
+
case out_format
|
12
|
+
when 'simple_html'
|
13
|
+
File.open("./tmp/api_doc.html", "w+") do |f|
|
14
|
+
f.write(ApiDocGeneration::Generation.new(codes_path).generate_html_string)
|
15
|
+
end
|
16
|
+
when 'detailed_html'
|
17
|
+
File.open("./tmp/api_detailed_doc.html", 'w+') do |f|
|
18
|
+
f.write(ApiDocGeneration::Generation.new(codes_path).generate_detailed_html_string)
|
19
|
+
end
|
20
|
+
else
|
21
|
+
puts "undefined OUT_FORMAT: '#{out_format}'"
|
10
22
|
end
|
11
23
|
end
|
12
24
|
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
4
|
+
|
5
|
+
<title>Uasthree Api Documents</title>
|
6
|
+
|
7
|
+
<link href='http://twitter.github.io/bootstrap/assets/css/bootstrap.css' rel='stylesheet'>
|
8
|
+
<style type='text/css'>
|
9
|
+
.title {
|
10
|
+
text-align: center;
|
11
|
+
color: blank;
|
12
|
+
}
|
13
|
+
|
14
|
+
.controller, .list {
|
15
|
+
width: 900px;
|
16
|
+
border: 1px solid;
|
17
|
+
margin: 20px auto 40 auto;
|
18
|
+
}
|
19
|
+
|
20
|
+
.list {
|
21
|
+
padding-top: 20px;
|
22
|
+
}
|
23
|
+
|
24
|
+
.controller-title {
|
25
|
+
text-align: center;
|
26
|
+
}
|
27
|
+
|
28
|
+
.action {
|
29
|
+
margin-top: 40px;
|
30
|
+
padding: 20px 40px 20px 20px;
|
31
|
+
}
|
32
|
+
|
33
|
+
.about {
|
34
|
+
padding-left: 20px;
|
35
|
+
}
|
36
|
+
|
37
|
+
.no_print {
|
38
|
+
opacity: 0.4;
|
39
|
+
}
|
40
|
+
|
41
|
+
.no_opacity {
|
42
|
+
opacity: 1;
|
43
|
+
}
|
44
|
+
|
45
|
+
@media print {
|
46
|
+
.no_print {
|
47
|
+
display: none;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
</style>
|
51
|
+
|
52
|
+
<script type='text/javascript' src='http://code.jquery.com/jquery-2.0.3.min.js'></script>
|
53
|
+
<script type='text/javascript'>
|
54
|
+
$(function(){
|
55
|
+
var no_print_class = 'no_print';
|
56
|
+
|
57
|
+
$('.print_selector').change(function(event){
|
58
|
+
var $this = $(this);
|
59
|
+
var $a = $this.next();
|
60
|
+
var $top = $a.parent();
|
61
|
+
var $target_el = $($a.attr('href'));
|
62
|
+
|
63
|
+
if ($this.is(":checked")) {
|
64
|
+
$top.removeClass(no_print_class)
|
65
|
+
$target_el.removeClass(no_print_class);
|
66
|
+
} else {
|
67
|
+
$top.addClass(no_print_class)
|
68
|
+
$target_el.addClass(no_print_class);
|
69
|
+
}
|
70
|
+
});
|
71
|
+
});
|
72
|
+
</script>
|
73
|
+
</head>
|
74
|
+
|
75
|
+
<body>
|
76
|
+
<h1 class='title'>Uasthree Api Document</h1>
|
77
|
+
|
78
|
+
<div class='list'>
|
79
|
+
<strong class='no_print no_opacity about'>* 被勾选的内容将被打印</strong>
|
80
|
+
|
81
|
+
<ul>
|
82
|
+
<% @documents.each do |controller| %>
|
83
|
+
<li>
|
84
|
+
<input type='checkbox' class='no_print no_opacity print_selector' checked=1 />
|
85
|
+
<a href='#<%= controller_identifer(controller[:klass]) %>'><%= controller[:about] %></a>
|
86
|
+
|
87
|
+
<ul class='ul-controller'>
|
88
|
+
<% controller[:actions].each do |action| %>
|
89
|
+
<li>
|
90
|
+
<input type='checkbox' class='no_print no_opacity print_selector' checked=1 />
|
91
|
+
<a href='#<%= action_identifer(controller[:klass], action[:name]) %>'>
|
92
|
+
<%= action[:desc] %>
|
93
|
+
</a>
|
94
|
+
</li>
|
95
|
+
<% end %>
|
96
|
+
</ul>
|
97
|
+
|
98
|
+
</li>
|
99
|
+
<% end %>
|
100
|
+
</ul>
|
101
|
+
</div>
|
102
|
+
|
103
|
+
<% @documents.each do |controller| %>
|
104
|
+
<div class='controller' id='<%= controller_identifer(controller[:klass]) %>'>
|
105
|
+
<h2 class='controller-title'><%= controller[:about] %></h2>
|
106
|
+
|
107
|
+
<% controller[:actions].each_with_index do |action, i| %>
|
108
|
+
<div class='action action-<%= i % 2 == 0 ? 'even' : 'odd' %>'
|
109
|
+
id='<%= action_identifer(controller[:klass], action[:name]) %>'>
|
110
|
+
|
111
|
+
<strong>功能说明</strong>
|
112
|
+
<p class='about'><%= action[:desc] %></p>
|
113
|
+
|
114
|
+
<strong>请求地址</strong>
|
115
|
+
<p class='about'><%= action[:path] %></p>
|
116
|
+
|
117
|
+
<strong>请求方法</strong>
|
118
|
+
<p class='about'><%= action[:method] %></p>
|
119
|
+
|
120
|
+
<strong>参数说明</strong>
|
121
|
+
<table class='table table-bordered table-striped'>
|
122
|
+
<thead>
|
123
|
+
<th>参数名</th>
|
124
|
+
<th>参数类型</th>
|
125
|
+
<th>描述</th>
|
126
|
+
</thead>
|
127
|
+
|
128
|
+
<tbody>
|
129
|
+
<% action['Params'].each do |param| %>
|
130
|
+
<% format_param(param) %>
|
131
|
+
|
132
|
+
<tr>
|
133
|
+
<% [:name, :type].each do |key| %>
|
134
|
+
<td><%= param[key] %></td>
|
135
|
+
<% end %>
|
136
|
+
|
137
|
+
<td>
|
138
|
+
<%= param[:val] %>
|
139
|
+
|
140
|
+
<% if param[:children] %>
|
141
|
+
<% param[:children].each do |cp| %>
|
142
|
+
<p style='padding-left: <%= (cp[:level] - 1) * 20 %>px'><%= cp[:desc] %></p>
|
143
|
+
<% end %>
|
144
|
+
<% end %>
|
145
|
+
</td>
|
146
|
+
|
147
|
+
</tr>
|
148
|
+
<% end %>
|
149
|
+
</tbody>
|
150
|
+
</table>
|
151
|
+
|
152
|
+
<strong>正常返回信息</strong>
|
153
|
+
<table class='table table-bordered table-striped'>
|
154
|
+
<thead>
|
155
|
+
<th>参数名</th>
|
156
|
+
<th>参数类型</th>
|
157
|
+
<th>描述</th>
|
158
|
+
</thead>
|
159
|
+
|
160
|
+
<tbody>
|
161
|
+
<% (action['Return'] || []).each do |param| %>
|
162
|
+
<% format_error_param(param) %>
|
163
|
+
|
164
|
+
<tr>
|
165
|
+
<% [:name, :type, :val].each do |key| %>
|
166
|
+
<td><%= param[key] %></td>
|
167
|
+
<% end %>
|
168
|
+
</tr>
|
169
|
+
<% end %>
|
170
|
+
</tbody>
|
171
|
+
</table>
|
172
|
+
|
173
|
+
<strong>出错误时信息</strong>
|
174
|
+
<p class='about'>
|
175
|
+
出错时response.status 为 400.
|
176
|
+
|
177
|
+
<table class='table table-bordered table-striped'>
|
178
|
+
<thead>
|
179
|
+
<th>参数名</th>
|
180
|
+
<th>参数类型</th>
|
181
|
+
<th>描述</th>
|
182
|
+
</thead>
|
183
|
+
|
184
|
+
<tbody>
|
185
|
+
<tr>
|
186
|
+
<td>error</td>
|
187
|
+
<td>String</td>
|
188
|
+
<td>错误标识</td>
|
189
|
+
</tr>
|
190
|
+
|
191
|
+
<tr>
|
192
|
+
<td>error_description</td>
|
193
|
+
<td>String</td>
|
194
|
+
<td>错误具体描述</td>
|
195
|
+
</tr>
|
196
|
+
</tbody>
|
197
|
+
</table>
|
198
|
+
|
199
|
+
</p>
|
200
|
+
|
201
|
+
<br /><hr />
|
202
|
+
</div>
|
203
|
+
<% end %>
|
204
|
+
|
205
|
+
</div>
|
206
|
+
<% end %>
|
207
|
+
</body>
|
208
|
+
</html>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_doc_generation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jiangzhi.xie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -57,6 +57,7 @@ files:
|
|
57
57
|
- lib/rake/api_doc_generation.rb
|
58
58
|
- lib/rake/tasks/api_doc.rake
|
59
59
|
- templates/doc.html.erb
|
60
|
+
- templates/doc_detailed.html.erb
|
60
61
|
homepage: ''
|
61
62
|
licenses:
|
62
63
|
- MIT
|