yard-api 0.1.10 → 0.2.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 +4 -4
- data/config/yard_api.yml +7 -4
- data/lib/yard-api/options.rb +4 -1
- data/lib/yard-api/tags/argument_tag.rb +32 -15
- data/lib/yard-api/tags.rb +2 -1
- data/lib/yard-api/templates/helpers/base_helper.rb +1 -1
- data/lib/yard-api/templates/helpers/html_helper.rb +31 -32
- data/lib/yard-api/verifier.rb +15 -3
- data/lib/yard-api/version.rb +1 -1
- data/lib/yard-api/yardoc_task.rb +7 -4
- data/lib/yard-api.rb +2 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/tags/argument_spec.rb +0 -1
- data/templates/api/appendix/json/setup.rb +25 -0
- data/templates/api/docstring/json/setup.rb +4 -0
- data/templates/api/fulldoc/html/setup.rb +1 -1
- data/templates/api/fulldoc/json/setup.rb +112 -0
- data/templates/api/layout/json/layout.erb +1 -0
- data/templates/api/layout/json/setup.rb +10 -0
- data/templates/api/method_details/html/header.erb +17 -6
- data/templates/api/method_details/html/method_signature.erb +9 -15
- data/templates/api/method_details/html/setup.rb +42 -19
- data/templates/api/method_details/json/setup.rb +9 -0
- data/templates/api/tags/html/argument/_list.erb +10 -18
- data/templates/api/tags/html/argument/_table.erb +13 -8
- data/templates/api/tags/setup.rb +1 -0
- data/templates/api/topic/html/setup.rb +11 -8
- data/templates/api/topic/json/setup.rb +25 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 867bf4c5f7af54dcfe89527e5aa33b3028573ae0
|
4
|
+
data.tar.gz: 55bee11b6e7fbf8a94f43e17750f908ca0ea286b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 855c761049489fe7c9f22fc786093580ee7de47ecd93a1f4945e70e35e64be2d1a1d4c780e0997101ea81fdfb4e48acb7b90a41f9b46acc1daa2ebcb172104fc
|
7
|
+
data.tar.gz: 3a0efa005c097a27e400ad6b00189aa8a3f57469929a9f37199766f00cb928f0a22004dca2f6daabf8dd7f66af284957e0be0a377f36aae533fa54d0ea089f0d
|
data/config/yard_api.yml
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
---
|
2
2
|
# config/yard_api.yml
|
3
3
|
output: public/doc/api
|
4
|
-
source: doc/api
|
5
4
|
readme: doc/api/README.md
|
6
5
|
|
7
6
|
# Title of the project. This will be displayed in the browser title bar as well
|
@@ -32,6 +31,8 @@ markup_provider:
|
|
32
31
|
files:
|
33
32
|
- app/controllers/**/*.rb
|
34
33
|
|
34
|
+
route_namespace:
|
35
|
+
|
35
36
|
# YARD assets that you want to reference from your docs. The key is the
|
36
37
|
# reference key you use in the docs, while the value is the path to where
|
37
38
|
# the assets are located relative to the doc source.
|
@@ -40,8 +41,8 @@ files:
|
|
40
41
|
#
|
41
42
|
# See "source" and "output".
|
42
43
|
assets:
|
43
|
-
images: images
|
44
|
-
examples: examples
|
44
|
+
# images: images
|
45
|
+
# examples: examples
|
45
46
|
|
46
47
|
# Debug option. YARD and YARD-API verbosity option.
|
47
48
|
verbose: true
|
@@ -57,7 +58,9 @@ strict: false
|
|
57
58
|
#
|
58
59
|
# Just specify the url to your repository and the branch the documentation has
|
59
60
|
# been generated for and things "should work".
|
60
|
-
|
61
|
+
#
|
62
|
+
# Example: https://github.com/amireh/yard-api
|
63
|
+
github_url:
|
61
64
|
github_branch: master
|
62
65
|
|
63
66
|
# Set to true if you want @argument tags to show up in a table instead of a list.
|
data/lib/yard-api/options.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
module YARD::APIPlugin
|
2
2
|
# See config/yard_api.yml for documentation for the options.
|
3
3
|
class Options < YARD::Options
|
4
|
+
default_attr :format, 'html'
|
5
|
+
default_attr :no_save, false
|
6
|
+
|
4
7
|
default_attr :title, 'Rails API Project'
|
5
8
|
default_attr :window_title, 'Rails API Project Documentation'
|
6
9
|
default_attr :version, ''
|
7
|
-
default_attr :source, 'doc/api'
|
8
10
|
default_attr :static, []
|
9
11
|
default_attr :files, []
|
10
12
|
default_attr :route_namespace, ''
|
@@ -15,6 +17,7 @@ module YARD::APIPlugin
|
|
15
17
|
default_attr :footer_note, ''
|
16
18
|
|
17
19
|
default_attr :one_file, false
|
20
|
+
default_attr :strict, false
|
18
21
|
default_attr :verbose, false
|
19
22
|
default_attr :debug, false
|
20
23
|
default_attr :theme, 'default'
|
@@ -7,6 +7,7 @@ module YARD::APIPlugin::Tags
|
|
7
7
|
RE_NAME = /^([\S]+)/
|
8
8
|
RE_ARRAY_LITERAL = /\[[^\]]+\]/
|
9
9
|
RE_ARRAY_TYPE = /^#{RE_ARRAY_LITERAL}$/
|
10
|
+
RE_REQUIRED_OPTIONAL = /required|optional/i
|
10
11
|
RE_ACCEPTED_VALUES_PREFIXES = /
|
11
12
|
accepted\svalues |
|
12
13
|
accepts |
|
@@ -38,18 +39,19 @@ module YARD::APIPlugin::Tags
|
|
38
39
|
YARD::Tags::Library.instance.tag_create(:attr, buf).tap do |tag|
|
39
40
|
super(:argument, tag.text, tag.types, name || tag.name)
|
40
41
|
|
42
|
+
@types ||= []
|
43
|
+
@text ||= ''
|
44
|
+
|
41
45
|
@is_required = parse_is_required(@types)
|
42
46
|
@accepted_values = parse_accepted_values(@types, @text)
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
46
50
|
def unscoped_name
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
@name
|
52
|
-
end
|
51
|
+
scope_tag = @object.tag(:argument_scope)
|
52
|
+
|
53
|
+
if scope_tag && @name =~ /^#{scope_tag.text.gsub(/\[\]/, '')}\[([^\]]+)\]$/
|
54
|
+
$1
|
53
55
|
else
|
54
56
|
@name
|
55
57
|
end
|
@@ -57,36 +59,51 @@ module YARD::APIPlugin::Tags
|
|
57
59
|
|
58
60
|
private
|
59
61
|
|
60
|
-
def parse_is_required(types)
|
62
|
+
def parse_is_required(types=[])
|
61
63
|
strict = !!YARD::APIPlugin.options.strict_arguments
|
62
|
-
specifier = types.detect { |typestr| typestr.match(
|
64
|
+
specifier = Array(types).detect { |typestr| typestr.match(RE_REQUIRED_OPTIONAL) }
|
63
65
|
|
64
66
|
if specifier
|
65
67
|
types.delete(specifier)
|
66
68
|
|
67
|
-
|
68
|
-
|
69
|
+
if specifier.downcase == 'required'
|
70
|
+
return true
|
71
|
+
elsif specifier.downcase == 'optional'
|
72
|
+
return false
|
73
|
+
end
|
69
74
|
end
|
70
75
|
|
71
76
|
strict
|
72
77
|
end
|
73
78
|
|
74
|
-
def parse_accepted_values(types, text)
|
75
|
-
|
79
|
+
def parse_accepted_values(types=[], text='')
|
80
|
+
# values specified after the type, i.e.:
|
81
|
+
#
|
82
|
+
# @argument [String, ["S","M","L"]] size
|
83
|
+
#
|
84
|
+
str = if Array(types).any? && types.last.match(RE_ARRAY_TYPE)
|
76
85
|
types.pop
|
77
|
-
|
86
|
+
# otherwise, look for them in the docstring, e.g.:
|
87
|
+
#
|
88
|
+
# @argument [String] size
|
89
|
+
# Accepts ["S","M","L"]
|
90
|
+
#
|
91
|
+
elsif text && text.match(RE_ACCEPTED_VALUES_STR)
|
78
92
|
$1
|
79
93
|
end
|
80
94
|
|
81
95
|
if str
|
82
96
|
begin
|
83
|
-
|
97
|
+
# some people prefer to use the pipe (|) to separate the values
|
98
|
+
YAML.load(str.to_s.gsub('|', ','))
|
84
99
|
rescue Exception => e
|
85
100
|
YARD::APIPlugin.on_error <<-Error
|
86
101
|
Unable to parse accepted values for @argument tag.
|
87
|
-
Error:
|
102
|
+
Error:
|
103
|
+
#{e.class}: #{e.message}
|
88
104
|
Offending docstring:
|
89
105
|
#{text}
|
106
|
+
Accepted values string: '#{str}'
|
90
107
|
Error
|
91
108
|
|
92
109
|
return nil
|
data/lib/yard-api/tags.rb
CHANGED
@@ -16,4 +16,5 @@ YARD::Tags::Library.define_tag("API empty response", :no_content)
|
|
16
16
|
YARD::Tags::Library.define_tag("API error", :throws)
|
17
17
|
YARD::Tags::Library.define_tag("API warning", :warning)
|
18
18
|
YARD::Tags::Library.define_tag("API note", :note)
|
19
|
-
YARD::Tags::Library.define_tag("API message", :emits)
|
19
|
+
YARD::Tags::Library.define_tag("API message", :emits)
|
20
|
+
YARD::Tags::Library.define_tag("API model", :model)
|
@@ -85,7 +85,7 @@ module YARD::Templates::Helpers::BaseHelper
|
|
85
85
|
def lookup_appendix(title)
|
86
86
|
appendix = nil
|
87
87
|
|
88
|
-
|
88
|
+
YARD::APIPlugin.log("Looking up appendix: #{title}") if api_options.verbose
|
89
89
|
|
90
90
|
if object
|
91
91
|
# try in the object scope
|
@@ -2,7 +2,7 @@ require 'yard/templates/helpers/html_helper'
|
|
2
2
|
|
3
3
|
module YARD::Templates::Helpers::HtmlHelper
|
4
4
|
def topicize(str)
|
5
|
-
str.gsub(' ', '_').underscore
|
5
|
+
str.split("\n")[0].gsub(' ', '_').underscore
|
6
6
|
end
|
7
7
|
|
8
8
|
def url_for_file(filename, anchor = nil)
|
@@ -12,55 +12,53 @@ module YARD::Templates::Helpers::HtmlHelper
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def static_pages()
|
15
|
-
|
15
|
+
@@static_pages ||= begin
|
16
|
+
locate_static_pages(YARD::APIPlugin.options)
|
17
|
+
end
|
18
|
+
end
|
16
19
|
|
17
|
-
|
20
|
+
def locate_static_pages(options)
|
21
|
+
title_overrides = {}
|
18
22
|
|
19
23
|
paths = Array(options.static).map do |entry|
|
20
24
|
pages = if entry.is_a?(Hash)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
raise "Invalid static page entry, expected Hash to contain a 'glob' parameter: #{entry}"
|
25
|
+
if !entry.has_key?('path')
|
26
|
+
raise "Static page entry must contain a 'path' parameter: #{entry}"
|
27
|
+
elsif !entry.has_key?('title')
|
28
|
+
raise "Static page entry must contain a 'title' parameter: #{entry}"
|
26
29
|
end
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
if blacklist.any?
|
31
|
-
pages.delete_if { |p| blacklist.any? { |filter| p.match(filter) } }
|
32
|
-
end
|
31
|
+
title_overrides[entry['path']] = entry['title']
|
33
32
|
|
34
|
-
|
33
|
+
entry['path']
|
35
34
|
elsif entry.is_a?(Array)
|
36
35
|
entry.map(&:to_s)
|
37
36
|
elsif entry.is_a?(String)
|
38
|
-
|
37
|
+
entry
|
39
38
|
end
|
40
|
-
end
|
39
|
+
end
|
41
40
|
|
42
|
-
|
43
|
-
readme_page = options.readme
|
44
|
-
pages = Dir.glob(paths)
|
41
|
+
pages = Dir.glob(paths.flatten.compact)
|
45
42
|
|
46
|
-
if
|
47
|
-
pages.delete_if { |page| page.match(
|
43
|
+
if options.readme && !options.one_file
|
44
|
+
pages.delete_if { |page| page.match(options.readme) }
|
48
45
|
end
|
49
46
|
|
50
|
-
|
47
|
+
pages.uniq.map do |page|
|
51
48
|
filename = 'file.' + File.split(page).last.sub(/\..*$/, '.html')
|
52
49
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
50
|
+
title = (
|
51
|
+
title_overrides[page] ||
|
52
|
+
File.basename(page)
|
53
|
+
.sub(/\.\w+$/, '')
|
54
|
+
.gsub('_', ' ')
|
55
|
+
.gsub(/\W/, ' ')
|
56
|
+
.gsub(/\s+/, ' ')
|
57
|
+
.capitalize
|
58
|
+
)
|
61
59
|
|
62
60
|
if options.verbose
|
63
|
-
puts "Serializing static page #{page}"
|
61
|
+
puts "Serializing static page #{page} (#{title})"
|
64
62
|
end
|
65
63
|
|
66
64
|
{
|
@@ -68,8 +66,9 @@ module YARD::Templates::Helpers::HtmlHelper
|
|
68
66
|
filename: filename,
|
69
67
|
title: title
|
70
68
|
}
|
71
|
-
end
|
69
|
+
end.sort_by { |page| page[:title] }
|
72
70
|
end
|
71
|
+
protected :locate_static_pages
|
73
72
|
|
74
73
|
# override yard-appendix link_appendix
|
75
74
|
def link_appendix(ref)
|
data/lib/yard-api/verifier.rb
CHANGED
@@ -10,9 +10,10 @@ module YARD
|
|
10
10
|
relevant = list.select { |o| relevant_object?(o) }
|
11
11
|
|
12
12
|
if @verbose && relevant.any?
|
13
|
-
|
13
|
+
log "#{relevant.length}/#{list.length} objects are relevant:"
|
14
|
+
|
14
15
|
relevant.each do |object|
|
15
|
-
|
16
|
+
log "\t- #{object.path}"
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
@@ -24,11 +25,22 @@ module YARD
|
|
24
25
|
when :root, :module, :constant
|
25
26
|
false
|
26
27
|
when :method, :class
|
27
|
-
!object.tags('API').empty?
|
28
|
+
is_api = !object.tags('API').empty?
|
29
|
+
is_internal = !object.tags('internal').empty?
|
30
|
+
|
31
|
+
if @verbose && !is_api && !is_internal
|
32
|
+
log "Resource #{object} will be ignored as it contains no @API tag."
|
33
|
+
end
|
34
|
+
|
35
|
+
is_api && !is_internal
|
28
36
|
else
|
29
37
|
object.parent.nil? && relevant_object?(object.parent)
|
30
38
|
end
|
31
39
|
end
|
40
|
+
|
41
|
+
def log(*args)
|
42
|
+
::YARD::APIPlugin.log(*args)
|
43
|
+
end
|
32
44
|
end
|
33
45
|
end
|
34
46
|
end
|
data/lib/yard-api/version.rb
CHANGED
data/lib/yard-api/yardoc_task.rb
CHANGED
@@ -14,7 +14,7 @@ module YARD::APIPlugin
|
|
14
14
|
@config = load_config
|
15
15
|
t = self
|
16
16
|
|
17
|
-
YARD::APIPlugin.options.update(@config)
|
17
|
+
api_options = YARD::APIPlugin.options.update(@config)
|
18
18
|
|
19
19
|
t.verifier = YARD::APIPlugin::Verifier.new(config['verbose'])
|
20
20
|
t.before = proc { FileUtils.rm_rf(config['output']) }
|
@@ -41,8 +41,11 @@ module YARD::APIPlugin
|
|
41
41
|
set_option('verbose') if config['verbose']
|
42
42
|
set_option('debug') if config['debug']
|
43
43
|
|
44
|
+
set_option('no-save') if config['no_save']
|
45
|
+
set_option('format', config['format'] || 'html')
|
46
|
+
|
44
47
|
get_assets(config).each_pair do |asset_id, rpath|
|
45
|
-
asset_path =
|
48
|
+
asset_path = rpath
|
46
49
|
|
47
50
|
if File.directory?(asset_path)
|
48
51
|
set_option 'asset', [ asset_path, asset_id ].join(':')
|
@@ -62,7 +65,7 @@ module YARD::APIPlugin
|
|
62
65
|
private
|
63
66
|
|
64
67
|
def load_config
|
65
|
-
path = Rails.root.join('config', 'yard_api.yml')
|
68
|
+
path = ENV.fetch('YARD_API_CONFIG') { Rails.root.join('config', 'yard_api.yml') }
|
66
69
|
|
67
70
|
# load defaults
|
68
71
|
config = YAML.load_file(File.join(YARD::APIPlugin::CONFIG_PATH, 'yard_api.yml'))
|
@@ -78,4 +81,4 @@ module YARD::APIPlugin
|
|
78
81
|
config['assets'] || {}
|
79
82
|
end
|
80
83
|
end
|
81
|
-
end
|
84
|
+
end
|
data/lib/yard-api.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
data/spec/tags/argument_spec.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
# include T('default/appendix/html')
|
2
|
+
|
3
|
+
def init
|
4
|
+
super
|
5
|
+
end
|
6
|
+
|
7
|
+
def appendix
|
8
|
+
controllers = options[:controllers]
|
9
|
+
|
10
|
+
if options[:all_resources]
|
11
|
+
controllers = options[:resources].flatten.select { |o|
|
12
|
+
o.is_a?(YARD::CodeObjects::NamespaceObject)
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
unless controllers && controllers.is_a?(Array)
|
17
|
+
return
|
18
|
+
end
|
19
|
+
|
20
|
+
@appendixes = controllers.collect do |controller|
|
21
|
+
controller.children.select { |tag| :appendix == tag.type }
|
22
|
+
end.flatten.uniq
|
23
|
+
|
24
|
+
super
|
25
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
include YARD::Templates::Helpers::ModuleHelper
|
4
|
+
include YARD::Templates::Helpers::FilterHelper
|
5
|
+
include YARD::Templates::Helpers::HtmlHelper
|
6
|
+
|
7
|
+
RouteHelper = YARD::Templates::Helpers::RouteHelper
|
8
|
+
|
9
|
+
def init
|
10
|
+
resources = options[:objects]
|
11
|
+
.group_by { |o| o.tags('API').first.text }
|
12
|
+
.sort_by { |o| o.first }
|
13
|
+
.each { |resource, controllers| serialize_resource(resource, controllers) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def serialize_resource(resource, controllers)
|
17
|
+
Templates::Engine.with_serializer("#{topicize resource}.json", options[:serializer]) do
|
18
|
+
JSON.pretty_generate({
|
19
|
+
object: resource,
|
20
|
+
api_objects: controllers.map do |controller|
|
21
|
+
dump_api_objects(controller)
|
22
|
+
end.flatten,
|
23
|
+
methods: method_details_list(controllers)
|
24
|
+
})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def method_details_list(controllers)
|
29
|
+
@meths = controllers.map do |controller|
|
30
|
+
controller.meths(:inherited => false, :included => false)
|
31
|
+
end.flatten
|
32
|
+
|
33
|
+
@meths = run_verifier(@meths)
|
34
|
+
|
35
|
+
@meths.map do |object, i|
|
36
|
+
dump_object(object).tap do |object_info|
|
37
|
+
object_info[:tags] = dump_object_tags(object)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def dump_api_objects(controller)
|
43
|
+
(controller.tags(:object) + controller.tags(:model)).map do |obj|
|
44
|
+
name, schema = obj.text.split(%r{\n+}, 2).map(&:strip)
|
45
|
+
|
46
|
+
{
|
47
|
+
controller: controller.name,
|
48
|
+
name: name,
|
49
|
+
schema: schema
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def dump_object(object)
|
55
|
+
{
|
56
|
+
name: object.name,
|
57
|
+
route: get_route(object),
|
58
|
+
title: object.title,
|
59
|
+
type: object.type,
|
60
|
+
path: object.path,
|
61
|
+
namespace: object.namespace.path,
|
62
|
+
source: object.source,
|
63
|
+
source_type: object.source_type,
|
64
|
+
signature: object.signature,
|
65
|
+
files: object.files,
|
66
|
+
docstring: object.base_docstring,
|
67
|
+
dynamic: object.dynamic,
|
68
|
+
group: object.group,
|
69
|
+
visibility: object.visibility
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def dump_object_tags(object)
|
74
|
+
object.tags.map do |tag|
|
75
|
+
tag.instance_variables.reduce({}) do |out, var|
|
76
|
+
key = var.to_s.sub('@', '')
|
77
|
+
|
78
|
+
if tag.respond_to?(key) && key != 'object'
|
79
|
+
out[key] = tag.send(key)
|
80
|
+
end
|
81
|
+
|
82
|
+
out
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_route(object)
|
88
|
+
controller = object.parent.path.underscore
|
89
|
+
controller.sub!("_controller", '') unless controller.include?('/')
|
90
|
+
|
91
|
+
action = object.path.sub(/^.*#/, '')
|
92
|
+
action = action.sub(/_with_.*$/, '')
|
93
|
+
routes = RouteHelper.api_methods_for_controller_and_action(controller, action)
|
94
|
+
route = routes.first
|
95
|
+
|
96
|
+
if route.present?
|
97
|
+
# controller_path = "app/controllers/#{route.requirements[:controller]}_controller.rb"
|
98
|
+
# controller_path = nil unless File.file?(Rails.root+controller_path)
|
99
|
+
|
100
|
+
route_path = route.path.spec.to_s.gsub("(.:format)", "")
|
101
|
+
verb = if route.verb.source =~ /\^?(\w*)\$/
|
102
|
+
$1.upcase
|
103
|
+
else
|
104
|
+
route.verb.source
|
105
|
+
end
|
106
|
+
|
107
|
+
{
|
108
|
+
path: route_path,
|
109
|
+
verb: verb
|
110
|
+
}
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= yieldall %>
|
@@ -1,13 +1,24 @@
|
|
1
|
-
<div class=
|
2
|
-
<h2
|
3
|
-
|
4
|
-
|
1
|
+
<div class='method_details'>
|
2
|
+
<h2
|
3
|
+
class='api_method_name'
|
4
|
+
name='<%= @props[:method_link] %>'
|
5
|
+
data-subtopic='<%= @props[:subtopic] %>'
|
6
|
+
>
|
7
|
+
<a
|
8
|
+
name='<%= @props[:method_link] %>'
|
9
|
+
href='#<%= @props[:method_link] %>'
|
10
|
+
>
|
11
|
+
<%= object.tag('API').text %>
|
5
12
|
</a>
|
6
13
|
|
7
|
-
<% if @
|
14
|
+
<% if @props[:path] && !api_options.github_url.to_s.empty? %>
|
8
15
|
<span class='defined-in'>
|
9
|
-
<a href="<%= api_options.github_url %>/blob/<%= api_options.github_branch %>/<%= @
|
16
|
+
<a href="<%= api_options.github_url %>/blob/<%= api_options.github_branch %>/<%= @props[:path] %>">
|
17
|
+
<%= "#{@props[:controller]}Controller\##{@props[:action]}" %>
|
18
|
+
</a>
|
19
|
+
</span>
|
10
20
|
<% end %>
|
11
21
|
</h2>
|
22
|
+
|
12
23
|
<%= yieldall %>
|
13
24
|
</div>
|
@@ -1,19 +1,13 @@
|
|
1
|
-
<% @routes.each do |route| %>
|
2
|
-
<%
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
<% @props[:routes].each do |route| %>
|
2
|
+
<%
|
3
|
+
formatted_route_path = route[:path].split('/').map do |fragment|
|
4
|
+
is_id = fragment =~ /^\:[\w|_]+/
|
5
|
+
"<span #{'class="id-fragment"' if is_id}>#{fragment}</span>"
|
6
|
+
end.join('/')
|
7
|
+
%>
|
8
|
+
|
9
9
|
<h3 class='endpoint'>
|
10
|
-
<span class="verb <%= verb.downcase %>"><%= verb %></span>
|
11
|
-
<%
|
12
|
-
formatted_route_path = route_path.split('/').map do |fragment|
|
13
|
-
is_id = fragment =~ /^\:[\w|_]+/
|
14
|
-
"<span #{'class="id-fragment"' if is_id}>#{fragment}</span>"
|
15
|
-
end.join('/')
|
16
|
-
%>
|
10
|
+
<span class="verb <%= route[:verb].downcase %>"><%= route[:verb] %></span>
|
17
11
|
<%= formatted_route_path %>
|
18
12
|
</h3>
|
19
13
|
<% end %>
|
@@ -1,35 +1,58 @@
|
|
1
1
|
# require 'route_helper'
|
2
2
|
|
3
3
|
RouteHelper = YARD::Templates::Helpers::RouteHelper
|
4
|
+
|
4
5
|
def init
|
5
|
-
get_routes
|
6
6
|
sections :header, [:method_signature, T('docstring')]
|
7
7
|
end
|
8
8
|
|
9
9
|
def header
|
10
|
-
|
11
|
-
|
10
|
+
routes = get_current_routes
|
11
|
+
|
12
|
+
unless route = routes.first
|
13
|
+
::YARD::APIPlugin.log(
|
14
|
+
"[error] Unable to find route for object: #{object}",
|
15
|
+
::Logger::ERROR
|
16
|
+
)
|
12
17
|
|
13
|
-
unless route = @routes.first
|
14
|
-
puts "[error] Unable to find route for object: #{object}"
|
15
18
|
return
|
16
19
|
end
|
17
20
|
|
18
|
-
@
|
19
|
-
@
|
21
|
+
@props = {}
|
22
|
+
@props[:method_link] = [
|
23
|
+
'method',
|
24
|
+
route.requirements[:controller],
|
25
|
+
route.requirements[:action]
|
26
|
+
].join('.')
|
27
|
+
|
28
|
+
@props[:subtopic] = (object.parent.tag('subtopic') || object.parent.tag('API')).text
|
29
|
+
|
30
|
+
controller_path = "app/controllers/#{route.requirements[:controller]}_controller.rb"
|
31
|
+
|
32
|
+
# TODO: can't we just test using object.file instead of relying on Rails ?
|
33
|
+
controller_path = nil unless File.file?(Rails.root+controller_path)
|
34
|
+
|
35
|
+
if controller_path
|
36
|
+
@props[:path] = controller_path
|
37
|
+
@props[:controller] = route.requirements[:controller].camelize
|
38
|
+
@props[:action] = route.requirements[:action]
|
39
|
+
end
|
40
|
+
|
41
|
+
@props[:routes] = routes.map do |route|
|
42
|
+
{}.tap do |spec|
|
43
|
+
spec[:path] = route.path.spec.to_s.gsub("(.:format)", "")
|
44
|
+
spec[:verb] = route.verb.source =~ /\^?(\w*)\$/ ? $1.upcase : route.verb.source
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
20
48
|
erb(:header)
|
21
49
|
end
|
22
50
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@route = @routes.first
|
31
|
-
if @route.present?
|
32
|
-
@controller_path = "app/controllers/#{@route.requirements[:controller]}_controller.rb"
|
33
|
-
@controller_path = nil unless File.file?(Rails.root+@controller_path)
|
34
|
-
end
|
51
|
+
def get_current_routes
|
52
|
+
controller_name = object.parent.path.underscore
|
53
|
+
controller_name.sub!("_controller", '') unless controller_name.include?('/')
|
54
|
+
|
55
|
+
action = object.path.sub(/^.*#/, '').sub(/_with_.*$/, '')
|
56
|
+
|
57
|
+
RouteHelper.api_methods_for_controller_and_action(controller_name, action)
|
35
58
|
end
|
@@ -1,28 +1,20 @@
|
|
1
1
|
<ul class="argument">
|
2
2
|
<% @argument_tags.each do |tag| %>
|
3
|
-
<%
|
4
|
-
tag.text ||= ''
|
5
|
-
desc = tag.text.strip.sub(/^\[([^\]]+)\]/, '').strip
|
6
|
-
type = $1
|
7
|
-
desc = desc.sub(/(\(optional\))/, '').strip
|
8
|
-
is_optional = $1.present?
|
9
|
-
name, desc = desc.split(/\s/, 2).map(&:strip)
|
10
|
-
desc = desc.sub(/[A|a]ccepted values:\s*\[([^\]]+)\]/, '').strip
|
11
|
-
accepted_values = $1
|
12
|
-
%>
|
13
3
|
<li>
|
14
|
-
<code class="argument-name"><%= h
|
15
|
-
<span class="argument-type"><%= type %></span>
|
16
|
-
|
17
|
-
<
|
18
|
-
|
4
|
+
<code class="argument-name"><%= h tag.unscoped_name %></code>
|
5
|
+
<span class="argument-type"><%= tag.type %></span>
|
6
|
+
<% if (tag.accepted_values || []).any? %>
|
7
|
+
<span class="argument-values fade">
|
8
|
+
<em>[ <%= tag.accepted_values.join(', ') %> ]</em>
|
9
|
+
</span>
|
10
|
+
<% end %>
|
19
11
|
|
20
|
-
<%
|
12
|
+
<% if tag.is_required %>
|
21
13
|
<em class="argument-required">Required</em>
|
22
14
|
<% end %>
|
23
15
|
|
24
|
-
<% if !
|
25
|
-
<%= html_markup_markdown(
|
16
|
+
<% if !tag.text.empty? %>
|
17
|
+
<%= html_markup_markdown(tag.text) %>
|
26
18
|
<% end %>
|
27
19
|
</li>
|
28
20
|
<% end %>
|
@@ -1,9 +1,11 @@
|
|
1
|
+
<% has_accepted_values = @argument_tags.any? { |e| Array(e.accepted_values).any? } %>
|
2
|
+
|
1
3
|
<table>
|
2
4
|
<thead>
|
3
5
|
<tr>
|
4
6
|
<th>Name</th>
|
5
7
|
<th>Type</th>
|
6
|
-
|
8
|
+
<% if has_accepted_values %><th>Accepted Values</th><% end %>
|
7
9
|
<th>Required?</th>
|
8
10
|
<th>Description</th>
|
9
11
|
</tr>
|
@@ -14,13 +16,16 @@
|
|
14
16
|
<tr>
|
15
17
|
<td><code class="argument-name"><%= h tag.unscoped_name %></code></td>
|
16
18
|
<td><span class="argument-type"><%= tag.type %></span></td>
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
|
20
|
+
<% if has_accepted_values %>
|
21
|
+
<td>
|
22
|
+
<ul class="argument-values">
|
23
|
+
<% (tag.accepted_values || []).each do |value| %>
|
24
|
+
<li><%= value %></li>
|
25
|
+
<% end %>
|
26
|
+
</ul>
|
27
|
+
</td>
|
28
|
+
<% end %>
|
24
29
|
|
25
30
|
<td>
|
26
31
|
<% if tag.is_required %>
|
data/templates/api/tags/setup.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
1
3
|
def init
|
2
4
|
sections :header, [:topic_doc, :method_details_list, [T('method_details')]]
|
3
5
|
@resource = object
|
@@ -19,16 +21,17 @@ def topic_doc
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def properties_of_model(json)
|
22
|
-
|
23
|
-
|
24
|
-
rescue JSON::ParserError
|
25
|
-
|
24
|
+
begin
|
25
|
+
JSON::parse(json || '')['properties']
|
26
|
+
rescue JSON::ParserError
|
27
|
+
nil
|
28
|
+
end
|
26
29
|
end
|
27
30
|
|
28
31
|
def word_wrap(text, col_width=80)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
text.gsub!( /(\S{#{col_width}})(?=\S)/, '\1 ' )
|
33
|
+
text.gsub!( /(.{1,#{col_width}})(?:\s+|$)/, "\\1\n" )
|
34
|
+
text
|
32
35
|
end
|
33
36
|
|
34
37
|
def indent(str, amount = 2, char = ' ')
|
@@ -36,7 +39,7 @@ def indent(str, amount = 2, char = ' ')
|
|
36
39
|
end
|
37
40
|
|
38
41
|
def render_comment(string, wrap = 75)
|
39
|
-
indent(word_wrap(string), 2, '/')
|
42
|
+
string ? indent(word_wrap(string), 2, '/') : ''
|
40
43
|
end
|
41
44
|
|
42
45
|
def render_value(value, type = 'string')
|
@@ -0,0 +1,25 @@
|
|
1
|
+
def init
|
2
|
+
# sections :header, [:topic_doc, :method_details_list, [T('method_details')]]
|
3
|
+
sections :method_details_list, [T('method_details')]
|
4
|
+
@resource = object
|
5
|
+
# @beta = options[:controllers].any? { |c| c.tag('beta') }
|
6
|
+
puts "Topic: HEE? #{@resource}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_details_list
|
10
|
+
@meths = options[:controllers].map { |c| c.meths(:inherited => false, :included => false) }.flatten
|
11
|
+
@meths = run_verifier(@meths)
|
12
|
+
|
13
|
+
# puts "Methods: #{@meths}"
|
14
|
+
|
15
|
+
buffer = [];
|
16
|
+
|
17
|
+
@meths.each_with_index do |meth, i|
|
18
|
+
# puts "#{i} => #{meth.tags}"
|
19
|
+
buffer.push(yieldall :object => meth, :index => i)
|
20
|
+
end
|
21
|
+
|
22
|
+
puts "Buffer: #{buffer.to_json}"
|
23
|
+
|
24
|
+
buffer.to_json
|
25
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yard-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ahmad Amireh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yard
|
@@ -93,8 +93,10 @@ files:
|
|
93
93
|
- spec/tags/argument_spec.rb
|
94
94
|
- tasks/yard_api.rake
|
95
95
|
- templates/api/appendix/html/setup.rb
|
96
|
+
- templates/api/appendix/json/setup.rb
|
96
97
|
- templates/api/docstring/html/setup.rb
|
97
98
|
- templates/api/docstring/html/text.erb
|
99
|
+
- templates/api/docstring/json/setup.rb
|
98
100
|
- templates/api/fulldoc/html/css/common.css
|
99
101
|
- templates/api/fulldoc/html/css/highlight.css
|
100
102
|
- templates/api/fulldoc/html/js/highlight.zip
|
@@ -157,6 +159,7 @@ files:
|
|
157
159
|
- templates/api/fulldoc/html/js/highlight/styles/zenburn.css
|
158
160
|
- templates/api/fulldoc/html/js/jquery-1.11.1.min.js
|
159
161
|
- templates/api/fulldoc/html/setup.rb
|
162
|
+
- templates/api/fulldoc/json/setup.rb
|
160
163
|
- templates/api/layout/html/_dynamic_styles.erb
|
161
164
|
- templates/api/layout/html/footer.erb
|
162
165
|
- templates/api/layout/html/headers.erb
|
@@ -164,9 +167,12 @@ files:
|
|
164
167
|
- templates/api/layout/html/scripts.erb
|
165
168
|
- templates/api/layout/html/setup.rb
|
166
169
|
- templates/api/layout/html/sidebar.erb
|
170
|
+
- templates/api/layout/json/layout.erb
|
171
|
+
- templates/api/layout/json/setup.rb
|
167
172
|
- templates/api/method_details/html/header.erb
|
168
173
|
- templates/api/method_details/html/method_signature.erb
|
169
174
|
- templates/api/method_details/html/setup.rb
|
175
|
+
- templates/api/method_details/json/setup.rb
|
170
176
|
- templates/api/onefile/html/setup.rb
|
171
177
|
- templates/api/onefile/html/sidebar.erb
|
172
178
|
- templates/api/tags/html/_example_code_block.erb
|
@@ -189,6 +195,7 @@ files:
|
|
189
195
|
- templates/api/topic/html/method_details_list.erb
|
190
196
|
- templates/api/topic/html/setup.rb
|
191
197
|
- templates/api/topic/html/topic_doc.erb
|
198
|
+
- templates/api/topic/json/setup.rb
|
192
199
|
- yard-api.gemspec
|
193
200
|
homepage: https://github.com/amireh/yard-api
|
194
201
|
licenses:
|