api_doc_generation 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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
|