rapi_doc 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.project +17 -0
- data/.rvmrc +1 -1
- data/Gemfile +5 -3
- data/Gemfile.lock +9 -3
- data/README.md +124 -13
- data/Rakefile +6 -4
- data/VERSION +1 -1
- data/autoscan.log +0 -0
- data/configure.scan +17 -0
- data/lib/rapi_doc.rb +75 -51
- data/lib/rapi_doc/method_doc.rb +71 -0
- data/lib/rapi_doc/rapi_config.rb +40 -0
- data/lib/rapi_doc/resource_doc.rb +85 -0
- data/lib/rapi_doc/tasks/rapi_doc_tasks.rake +29 -30
- data/templates/Search.png +0 -0
- data/templates/_resource_header.html.haml +17 -0
- data/templates/_resource_method.html.haml +38 -0
- data/templates/index.html.haml +40 -0
- data/templates/scripts.js +22 -0
- data/templates/styles.css +80 -0
- metadata +75 -29
- data/lib/doc_parser.rb +0 -53
- data/lib/doc_util.rb +0 -8
- data/lib/method_doc.rb +0 -44
- data/lib/rapi_config.rb +0 -37
- data/lib/resource_doc.rb +0 -102
- data/templates/_resource_header.html.erb +0 -18
- data/templates/_resource_method.html.erb +0 -56
- data/templates/class_layout.html.erb +0 -36
- data/templates/config.yml +0 -3
- data/templates/frameset.html.erb +0 -11
- data/templates/layout.html.erb +0 -69
- data/templates/main.html.erb +0 -15
data/.project
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<projectDescription>
|
3
|
+
<name>rapi_doc</name>
|
4
|
+
<comment></comment>
|
5
|
+
<projects>
|
6
|
+
</projects>
|
7
|
+
<buildSpec>
|
8
|
+
<buildCommand>
|
9
|
+
<name>com.aptana.ide.core.unifiedBuilder</name>
|
10
|
+
<arguments>
|
11
|
+
</arguments>
|
12
|
+
</buildCommand>
|
13
|
+
</buildSpec>
|
14
|
+
<natures>
|
15
|
+
<nature>com.aptana.ruby.core.rubynature</nature>
|
16
|
+
</natures>
|
17
|
+
</projectDescription>
|
data/.rvmrc
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rvm ruby-1.9.2
|
1
|
+
rvm ruby-1.9.2@rapidoc --create
|
data/Gemfile
CHANGED
@@ -4,12 +4,14 @@ source "http://rubygems.org"
|
|
4
4
|
# gem "activesupport", ">= 2.3.5"
|
5
5
|
|
6
6
|
gem 'activesupport', '>= 2.1'
|
7
|
+
gem 'haml'
|
8
|
+
gem 'rdoc'
|
7
9
|
|
8
10
|
# Add dependencies to develop your gem here.
|
9
11
|
# Include everything needed to run rake, tests, features, etc.
|
10
12
|
group :development do
|
11
|
-
gem "rspec", "
|
12
|
-
gem "bundler", "
|
13
|
-
gem "jeweler", "
|
13
|
+
gem "rspec", ">= 2.7.0"
|
14
|
+
gem "bundler", ">= 1.0.0"
|
15
|
+
gem "jeweler", ">= 1.6.4"
|
14
16
|
gem "rcov", ">= 0"
|
15
17
|
end
|
data/Gemfile.lock
CHANGED
@@ -5,13 +5,17 @@ GEM
|
|
5
5
|
multi_json (~> 1.0)
|
6
6
|
diff-lcs (1.1.3)
|
7
7
|
git (1.2.5)
|
8
|
+
haml (3.1.4)
|
8
9
|
jeweler (1.6.4)
|
9
10
|
bundler (~> 1.0)
|
10
11
|
git (>= 1.2.5)
|
11
12
|
rake
|
13
|
+
json (1.6.6)
|
12
14
|
multi_json (1.0.4)
|
13
15
|
rake (0.9.2.2)
|
14
16
|
rcov (0.9.11)
|
17
|
+
rdoc (3.12)
|
18
|
+
json (~> 1.4)
|
15
19
|
rspec (2.7.0)
|
16
20
|
rspec-core (~> 2.7.0)
|
17
21
|
rspec-expectations (~> 2.7.0)
|
@@ -26,7 +30,9 @@ PLATFORMS
|
|
26
30
|
|
27
31
|
DEPENDENCIES
|
28
32
|
activesupport (>= 2.1)
|
29
|
-
bundler (
|
30
|
-
|
33
|
+
bundler (>= 1.0.0)
|
34
|
+
haml
|
35
|
+
jeweler (>= 1.6.4)
|
31
36
|
rcov
|
32
|
-
|
37
|
+
rdoc
|
38
|
+
rspec (>= 2.7.0)
|
data/README.md
CHANGED
@@ -13,19 +13,78 @@ Installation
|
|
13
13
|
Usage
|
14
14
|
=====
|
15
15
|
|
16
|
-
Run `rake rapi_doc:setup` to generate
|
17
|
-
|
18
|
-
Modify config file by adding your controllers, e.g.:
|
19
|
-
|
20
|
-
books:
|
21
|
-
location: "/books"
|
22
|
-
controller_name: "books_controller.rb"
|
16
|
+
Run `rake rapi_doc:setup` to generate default Haml template files along with default styles.
|
17
|
+
These files are in `<application folder>/config/rapi_doc` folder.
|
23
18
|
|
24
19
|
Then invoke the generation by calling:
|
25
20
|
|
26
21
|
`rake rapi_doc:generate`
|
27
22
|
|
28
|
-
|
23
|
+
It will analyze `rake routes` output and find the controller files in app/controllers directory that may have the annotation.
|
24
|
+
It will confirm from the user whether he/she wants the plugin to look for annotations in each of these files.
|
25
|
+
For files confirmed by the user, it will parse the annotations and generate the HTML output using the template files and styles
|
26
|
+
in the `config/rapi_doc` folder.
|
27
|
+
|
28
|
+
`rake rapi_doc:clean`
|
29
|
+
will remove the documentation thus generated.
|
30
|
+
|
31
|
+
`rake rapi_doc:distclean`
|
32
|
+
will remove the documentation and also the Haml template files and styles created by the `rake rapi_doc:setup`
|
33
|
+
|
34
|
+
|
35
|
+
Markup Reference
|
36
|
+
================
|
37
|
+
|
38
|
+
Controller methods and controllers themselves are documented by annotating them with "method markers" and
|
39
|
+
"resource markers" enclosed in "apidoc" comments, similar to that in RDoc.
|
40
|
+
|
41
|
+
# =begin apidoc
|
42
|
+
... method markers
|
43
|
+
# =end
|
44
|
+
|
45
|
+
A] Method markers
|
46
|
+
-----------------
|
47
|
+
|
48
|
+
Method markers are specified like this:
|
49
|
+
|
50
|
+
# <<method-marker-name>:: <method-marker-value>
|
51
|
+
|
52
|
+
All method markers are optional.
|
53
|
+
|
54
|
+
# method: HTTP request type such as GET or POST
|
55
|
+
# access: access restrictions such as FREE, RESTRICTED for paid subscribers, etc
|
56
|
+
# return: list of return data-formats like [JSON|XML] and what the return data means
|
57
|
+
# param: name and type of the parameter expected
|
58
|
+
# output: output format like JSON, XML. It is recommended that it should include an example of such data.
|
59
|
+
# Each output marker must end with ::output-end:: on a separate line.
|
60
|
+
# request: a request generating code example
|
61
|
+
# response: a response processing code example
|
62
|
+
|
63
|
+
You can define your own custom method markers as well.
|
64
|
+
They will be available as the instance variables against which the _resource_method.html.erb template
|
65
|
+
will be evaluated.
|
66
|
+
|
67
|
+
Any other information that needs to be shown in the view can be specified in the apidoc comments as well.
|
68
|
+
It will be shown under the "Description" section for the method in the view.
|
69
|
+
|
70
|
+
|
71
|
+
B] Resource markers
|
72
|
+
-------------------
|
73
|
+
|
74
|
+
A resource, which is normally a controller object, can also be annotated with apidoc comments.
|
75
|
+
|
76
|
+
Method markers are specified the same way as the method markers:
|
77
|
+
|
78
|
+
# <<method-marker-name>:: <method-marker-value>
|
79
|
+
#
|
80
|
+
# xml: xml representation of the resource
|
81
|
+
# json: json representation
|
82
|
+
|
83
|
+
Just like in method marker, any other information that needs to be shown in the view can be specified in the apidoc comments as well.
|
84
|
+
It will be shown under the "Description" section for the method in the view.
|
85
|
+
|
86
|
+
|
87
|
+
C] Documentation Example
|
29
88
|
---------------------
|
30
89
|
|
31
90
|
# =begin apidoc
|
@@ -63,14 +122,66 @@ Documentation Example
|
|
63
122
|
# Get a list of all books in the system with pagination. Defaults to 10 per page
|
64
123
|
# =end
|
65
124
|
|
66
|
-
|
67
|
-
Layout
|
68
|
-
------
|
69
125
|
|
70
|
-
|
126
|
+
|
127
|
+
Haml Templates and styles
|
128
|
+
=========================
|
129
|
+
|
130
|
+
Resource and resource method annotations are available as instance and local variables in Haml templates.
|
131
|
+
Here are the listing of variables available. But the best way to understand it is to look at the default
|
132
|
+
Haml templates generated by `rake rapi_doc:setup` in `config/rapi_doc` folder.
|
133
|
+
|
134
|
+
|
135
|
+
A] Resource Method
|
136
|
+
------------------
|
137
|
+
|
138
|
+
@resource_name: Resource name
|
139
|
+
@method_order: the numerical order of the method
|
140
|
+
@content: All Misc info
|
141
|
+
@url: url
|
142
|
+
@access: public/privileged, etc
|
143
|
+
@return: the data format of the info
|
144
|
+
@params: params expected by this api
|
145
|
+
@outputs: array of [output_format, output example], for example, [json, ....json output.. ]
|
146
|
+
@request: example of the data expected
|
147
|
+
@response: example of the response
|
148
|
+
|
149
|
+
|
150
|
+
B] Resource
|
151
|
+
-----------
|
152
|
+
|
153
|
+
@name: name
|
154
|
+
@xml: xml representation of the resource
|
155
|
+
@json: json representation
|
156
|
+
@function_blocks: Array of resource method objects described above
|
157
|
+
|
158
|
+
|
159
|
+
Following instance variables are only available in the index template described below (and not in the resource Haml template)
|
160
|
+
@resource_methods: Array of HTML generated for each of the methods.
|
161
|
+
@resource_header: HTML generated for the resource
|
162
|
+
|
163
|
+
|
164
|
+
C] Index
|
165
|
+
--------
|
166
|
+
|
167
|
+
resource_docs: all the resource objects, whose instance variables are described above.
|
168
|
+
As mentioned before, for each resource, the HTML generated for the resource itself is available in @resource_header
|
169
|
+
and HTML generated for each of its methods is available in @resource_methods array.
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
D] Documentaton Output
|
174
|
+
----------------------
|
175
|
+
|
176
|
+
Documentation generated is located in `public/apidoc` directory.
|
177
|
+
|
178
|
+
index.html: contains the HTML
|
179
|
+
styles.css: CSS styles
|
180
|
+
scripts.js: contains the script used to search within the documentation.
|
181
|
+
|
71
182
|
|
72
183
|
Credit
|
73
184
|
======
|
74
185
|
|
75
186
|
* Based on RAPI Doc by Jaap van der Meer found here: http://code.google.com/p/rapidoc/
|
76
|
-
* https://github.com/sabman/rapi_doc
|
187
|
+
* https://github.com/sabman/rapi_doc
|
data/Rakefile
CHANGED
@@ -18,10 +18,12 @@ Jeweler::Tasks.new do |gem|
|
|
18
18
|
gem.homepage = "http://github.com/elc/rapi_doc"
|
19
19
|
gem.license = "MIT"
|
20
20
|
gem.summary = %Q{Rails API Doc Generator}
|
21
|
-
gem.description = %Q{Rails API Doc Generator}
|
21
|
+
gem.description = %Q{Rails API Doc Generator. Parses the apidoc annotations to generate HTML pages.}
|
22
22
|
gem.email = "hchoroomi@gmail.com"
|
23
|
-
gem.authors = ["Husein Choroomi", "Adinda Praditya"]
|
23
|
+
gem.authors = ["Husein Choroomi", "Adinda Praditya", "Salil Wadnerkar"]
|
24
24
|
# dependencies defined in Gemfile
|
25
|
+
gem.add_dependency 'haml'
|
26
|
+
gem.add_dependency 'rdoc'
|
25
27
|
end
|
26
28
|
Jeweler::RubygemsDotOrgTasks.new
|
27
29
|
|
@@ -42,8 +44,8 @@ end
|
|
42
44
|
|
43
45
|
task :default => :test
|
44
46
|
|
45
|
-
require '
|
46
|
-
|
47
|
+
require 'rdoc/task'
|
48
|
+
RDoc::Task.new do |rdoc|
|
47
49
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
50
|
|
49
51
|
rdoc.rdoc_dir = 'rdoc'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/autoscan.log
ADDED
File without changes
|
data/configure.scan
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- Autoconf -*-
|
2
|
+
# Process this file with autoconf to produce a configure script.
|
3
|
+
|
4
|
+
AC_PREREQ(2.61)
|
5
|
+
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
|
6
|
+
|
7
|
+
# Checks for programs.
|
8
|
+
|
9
|
+
# Checks for libraries.
|
10
|
+
|
11
|
+
# Checks for header files.
|
12
|
+
|
13
|
+
# Checks for typedefs, structures, and compiler characteristics.
|
14
|
+
|
15
|
+
# Checks for library functions.
|
16
|
+
|
17
|
+
AC_OUTPUT
|
data/lib/rapi_doc.rb
CHANGED
@@ -1,76 +1,100 @@
|
|
1
|
-
require '
|
1
|
+
require 'haml'
|
2
2
|
require 'fileutils'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require 'rapi_doc/railtie' if defined?(Rails)
|
3
|
+
require_relative 'rapi_doc/resource_doc'
|
4
|
+
require_relative 'rapi_doc/rapi_config'
|
5
|
+
require_relative 'rapi_doc/railtie' if defined?(Rails)
|
7
6
|
|
8
7
|
module RapiDoc
|
9
|
-
|
8
|
+
module RAPIDoc
|
10
9
|
|
11
10
|
include RapiConfig
|
11
|
+
include FileUtils::Verbose # so that each mv/cp/mkdir gets printed and user is aware of what is happening
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
puts "Finished."
|
13
|
+
def create_structure!
|
14
|
+
File.directory?(config_dir) || mkdir(config_dir)
|
15
|
+
Dir["#{template_dir}/*.*"].each do |template_file|
|
16
|
+
target_file = config_dir(File.basename(template_file))
|
17
|
+
cp template_file, config_dir if not File.exist? target_file
|
18
|
+
end
|
20
19
|
end
|
21
20
|
|
22
|
-
#
|
23
|
-
|
24
|
-
|
21
|
+
# Reads 'rake routes' output and gets the controller info
|
22
|
+
def get_controller_info!
|
23
|
+
controller_info = {}
|
24
|
+
routes = Dir.chdir(::Rails.root.to_s) { `rake routes` }
|
25
|
+
routes.split("\n").each do |entry|
|
26
|
+
method, url, controller_action = entry.split.slice(-3, 3)
|
27
|
+
controller, action = controller_action.split('#')
|
28
|
+
puts "For \"#{controller}\", found action \"#{action}\" with #{method} at \"#{url}\""
|
29
|
+
controller_info[controller] ||= []
|
30
|
+
controller_info[controller] << [action, method, url]
|
31
|
+
end
|
32
|
+
controller_info
|
33
|
+
end
|
25
34
|
|
26
|
-
|
27
|
-
|
28
|
-
|
35
|
+
def get_resources!
|
36
|
+
#yml = get_config || []
|
37
|
+
#yml.collect { |key, val| ResourceDoc.new(key, val["location"], controller_dir(val["controller_name"])) }
|
38
|
+
controller_info = get_controller_info!
|
39
|
+
resources = []
|
40
|
+
controller_info.each do |controller, action_entries|
|
41
|
+
#controller_class = controller.capitalize + 'Controller'
|
42
|
+
controller_location = controller_dir(controller + '_controller.rb')
|
43
|
+
controller_base_routes = action_entries.select do |action, method, url|
|
44
|
+
url.index('/', 1).nil?
|
45
|
+
end
|
46
|
+
# base urls differ only by the method [GET or POST]. So, any one will do.
|
47
|
+
controller_url = controller_base_routes[0][2].gsub(/\(.*\)/, '') # omit the trailing format
|
48
|
+
#controller_methods = controller_base_routes.map { |action, method, url| method }
|
49
|
+
if block_given?
|
50
|
+
controller_include = yield [controller, controller_url, controller_location]
|
51
|
+
else
|
52
|
+
controller_include = true
|
53
|
+
end
|
54
|
+
resources << ResourceDoc.new(controller, controller_url, controller_location) if controller_include
|
29
55
|
end
|
30
|
-
|
31
|
-
copy_styles!
|
56
|
+
resources
|
32
57
|
end
|
33
58
|
|
34
|
-
#
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
File.open(class_layout_file(:target)).each { |line| template << line }
|
39
|
-
parsed = ERB.new(template).result(binding)
|
40
|
-
File.open(File.join(temp_dir, "class.html"), 'w') { |file| file.write parsed }
|
59
|
+
# Generates views and their index in a temp directory
|
60
|
+
def generate_templates!(resource_docs)
|
61
|
+
generate_resource_templates!(resource_docs)
|
62
|
+
copy_styles!
|
41
63
|
end
|
42
64
|
|
65
|
+
# Moves the generated files in the temp directory to target directory
|
43
66
|
def move_structure!
|
44
|
-
|
45
|
-
|
67
|
+
Dir.mkdir(target_dir) if (!File.directory?(target_dir))
|
68
|
+
# Only want to move the .html, .css, .png and .js files, not the .haml templates.
|
69
|
+
html_css_files = temp_dir("*.{html,css,js,png}")
|
70
|
+
Dir[html_css_files].each { |f| mv f, target_dir }
|
71
|
+
end
|
46
72
|
|
47
|
-
|
48
|
-
|
49
|
-
|
73
|
+
# Removes the generated files
|
74
|
+
def remove_structure!
|
75
|
+
rm_rf target_dir
|
76
|
+
end
|
50
77
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
78
|
+
# Remove all files - config and generated
|
79
|
+
def remove_all!
|
80
|
+
remove_structure!
|
81
|
+
rm_rf config_dir
|
82
|
+
end
|
55
83
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
84
|
+
# Creates views for the resources
|
85
|
+
def generate_resource_templates!(resource_docs)
|
86
|
+
class_template = IO.read(template_dir('_resource_header.html.haml'))
|
87
|
+
method_template = IO.read(template_dir('_resource_method.html.haml'))
|
88
|
+
resource_docs.each { |resource| resource.parse_apidoc!(class_template, method_template) }
|
89
|
+
template = IO.read(config_dir('index.html.haml'))
|
90
|
+
parsed = Haml::Engine.new(template).render(Object.new, :resource_docs => resource_docs)
|
91
|
+
File.open(temp_dir("index.html"), 'w') { |file| file.write parsed }
|
60
92
|
end
|
61
93
|
|
62
94
|
def copy_styles!
|
63
|
-
|
64
|
-
|
65
|
-
FileUtils.cp f, temp_dir
|
66
|
-
end
|
67
|
-
end
|
95
|
+
css_js_files = config_dir("*.{css,js,png}")
|
96
|
+
Dir[css_js_files].each { |f| cp f, temp_dir }
|
68
97
|
end
|
69
98
|
|
70
|
-
private
|
71
|
-
|
72
|
-
def temp_dir
|
73
|
-
@temp_dir ||= "#{Dir.mktmpdir("apidoc")}/"
|
74
|
-
end
|
75
99
|
end
|
76
100
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module RapiDoc
|
2
|
+
# This class holds methods about a doc.
|
3
|
+
class MethodDoc
|
4
|
+
attr_accessor :scope, :method_order, :content, :request, :response, :outputs, :params
|
5
|
+
|
6
|
+
def initialize(resource_name, type, order)
|
7
|
+
@resource_name = resource_name
|
8
|
+
@scope = type
|
9
|
+
@method_order = order
|
10
|
+
@content = ""
|
11
|
+
@request = ""
|
12
|
+
@response = ""
|
13
|
+
@outputs = {}
|
14
|
+
@params = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def process_line(line, current_scope)
|
18
|
+
#puts "In scope #{current_scope} processing: #{line}"
|
19
|
+
new_scope = current_scope
|
20
|
+
case current_scope
|
21
|
+
when :response
|
22
|
+
if line =~ /::response-end::/
|
23
|
+
new_scope = :function
|
24
|
+
else
|
25
|
+
@response << line
|
26
|
+
end
|
27
|
+
when :request
|
28
|
+
if line =~ /::request-end::/
|
29
|
+
new_scope = :function
|
30
|
+
else
|
31
|
+
@request << line
|
32
|
+
end
|
33
|
+
when :output # append output
|
34
|
+
if line =~ /::output-end::/
|
35
|
+
new_scope = :function
|
36
|
+
else
|
37
|
+
last_output_key = @outputs.keys.last
|
38
|
+
@outputs[last_output_key] << ERB::Util.html_escape(line)
|
39
|
+
end
|
40
|
+
when :class, :function
|
41
|
+
result = line.scan(/(\w+)\:\:\s*(.+)/)
|
42
|
+
if not result.empty?
|
43
|
+
key, value = result[0]
|
44
|
+
case key
|
45
|
+
when "response", "request"
|
46
|
+
new_scope = key.to_sym
|
47
|
+
when "output"
|
48
|
+
new_scope = key.to_sym
|
49
|
+
@outputs[value] = '' # add the new output format as a key
|
50
|
+
when "param"
|
51
|
+
@params << value
|
52
|
+
else # user wants this new shiny variable whose name is the key with value = value
|
53
|
+
instance_variable_set("@#{key}".to_sym, value)
|
54
|
+
define_singleton_method(key.to_sym) { value } # define accessor for the templates to read it
|
55
|
+
end
|
56
|
+
else
|
57
|
+
# add line to block
|
58
|
+
@content << line
|
59
|
+
end
|
60
|
+
else
|
61
|
+
raise ParsingException, "logic error: unknown current scope #{current_scope}"
|
62
|
+
end
|
63
|
+
new_scope
|
64
|
+
end
|
65
|
+
|
66
|
+
def get_binding
|
67
|
+
binding
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|