yard-api 0.1.10 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|