grape-docs 1.0.0
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 +7 -0
- data/README.md +54 -0
- data/bin/grape-docs +3 -0
- data/lib/grape_docs.rb +13 -0
- data/lib/grape_docs/api.rb +22 -0
- data/lib/grape_docs/command.rb +45 -0
- data/lib/grape_docs/endpoint.rb +30 -0
- data/lib/grape_docs/exporter.rb +62 -0
- data/lib/grape_docs/version.rb +3 -0
- metadata +150 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6480091004b71f2a3a6ddc2bf958f2f372d9fd24
|
4
|
+
data.tar.gz: 8817d24c6ae9b14813e4f91cf301917f4d76975d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 288642a1dc0c4163295cc6aea4feefc5cca8f69f4df890650aa1966cab83cd58a599aa0531ee0805e52b3114ccf53e234c86412d4f515bac03ab31389b5cf7ec
|
7
|
+
data.tar.gz: f1828a445b04cb792439f2e444778c2edbe1cd50d594ca3c529797fed751ba1304c80705afb3511b68de4393de4e8fbf2b1fc8671f67159299ad0223a1d3823a
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# grape-docs
|
2
|
+
|
3
|
+
> Automatically generate markdown documentation from your grape API
|
4
|
+
|
5
|
+
## Description
|
6
|
+
|
7
|
+
grape-docs automagically generates documentation for your Grape API in various formats.
|
8
|
+
|
9
|
+
The Gem will automatically analyze your Grape API structure, mounts, namespaces and routes, and will build a markdown documentation in separate files.
|
10
|
+
|
11
|
+
It's best used combined with [GitBook](https://www.gitbook.com) and [gitbook-plugin-api](https://github.com/MagLoft/gitbook-plugin-api) to transform your markdown documentation into a good-looking and browsable API navigation.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Install globally using `gem install grape-docs` or include it in your project Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
source 'http://rubygems.org'
|
19
|
+
|
20
|
+
gem 'grape-docs'
|
21
|
+
```
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Run the `grape-docs export` command to export your documentation from within your Grape API project directory:
|
26
|
+
|
27
|
+
```
|
28
|
+
Usage:
|
29
|
+
grape-docs export <api_name> <export_path>
|
30
|
+
|
31
|
+
Arguments:
|
32
|
+
<api_name> # Constant name of your Grape API, e.g. MyApp::Api
|
33
|
+
<export_path> # Directory / path where the markdown documentation will be generated in
|
34
|
+
|
35
|
+
Options:
|
36
|
+
-h, [--host=HOST] # API Host
|
37
|
+
# Default: https://api.example.com/
|
38
|
+
-t, [--template=TEMPLATE] # Markdown template (default, gitbook) or custom (requires .md.erb extension)
|
39
|
+
# Default: default
|
40
|
+
-r, [--require=REQUIRE] # Ruby environment require path
|
41
|
+
# Default: config/environment.rb
|
42
|
+
|
43
|
+
Export documentation of API named <api_name> to <export_path> directory
|
44
|
+
```
|
45
|
+
|
46
|
+
## Result
|
47
|
+
|
48
|
+
| Template `default` | Template `gitbook` |
|
49
|
+
| :----------------------------------------------------------------------: | :----------------------------------------------------------------------: |
|
50
|
+
|  |  |
|
51
|
+
|
52
|
+
## License
|
53
|
+
|
54
|
+
grape-docs is available under an MIT-style license.
|
data/bin/grape-docs
ADDED
data/lib/grape_docs.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "json"
|
3
|
+
require "workspace"
|
4
|
+
require "active_support/inflector"
|
5
|
+
require "grape_docs/api"
|
6
|
+
require "grape_docs/endpoint"
|
7
|
+
|
8
|
+
module GrapeDocs
|
9
|
+
@@config = { api_host: "https://api.example.com", template: "default" }
|
10
|
+
def self.config
|
11
|
+
@@config
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module GrapeDocs
|
2
|
+
class Api
|
3
|
+
attr_reader :title, :detail, :path, :url, :endpoints, :children
|
4
|
+
|
5
|
+
def initialize(grape)
|
6
|
+
desc = grape.inheritable_setting.namespace[:description]
|
7
|
+
@title = desc ? desc[:description] : grape.name.titlecase
|
8
|
+
@detail = desc ? desc[:detail] : nil
|
9
|
+
@path = File.join(grape.inheritable_setting.namespace_stackable[:mount_path])
|
10
|
+
@url = File.join(GrapeDocs.config[:api_host], @path)
|
11
|
+
@endpoints = []
|
12
|
+
@children = []
|
13
|
+
grape.endpoints.each do |endpoint|
|
14
|
+
if endpoint.options.key?(:app)
|
15
|
+
@children.push(Api.new(endpoint.options[:app]))
|
16
|
+
elsif endpoint.routes.count > 0
|
17
|
+
@endpoints.push(Endpoint.new(self, endpoint))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'pry'
|
2
|
+
require 'thor'
|
3
|
+
require 'grape_docs'
|
4
|
+
require 'grape_docs/version'
|
5
|
+
require 'grape_docs/exporter'
|
6
|
+
|
7
|
+
module GrapeDocs
|
8
|
+
class Command < Thor
|
9
|
+
map %w[--version -v] => :__print_version
|
10
|
+
desc "--version, -v", "print version number"
|
11
|
+
def __print_version
|
12
|
+
puts GrapeDocs::VERSION
|
13
|
+
end
|
14
|
+
desc "export <api_name> <export_path>", "Export documentation of API named <api_name> to <export_path> directory"
|
15
|
+
method_option :host, aliases: "-h", desc: "API Host", type: :string, default: "https://api.example.com/"
|
16
|
+
method_option :template, aliases: "-t", desc: "Markdown template (default, gitbook) or custom (requires .md.erb extension)", type: :string, default: "default"
|
17
|
+
method_option :require, aliases: "-r", desc: "Ruby environment require path", type: :string, default: "config/environment.rb"
|
18
|
+
def export(api_name, export_path)
|
19
|
+
# grape docs configuration
|
20
|
+
GrapeDocs.config[:api_host] = options.host
|
21
|
+
GrapeDocs.config[:template] = options.template
|
22
|
+
|
23
|
+
# prepare grape API
|
24
|
+
require_file = Workspace.file(options.require)
|
25
|
+
raise(Thor::Error, "ERROR: config/environment.rb doesn't exists!") unless require_file.exists?
|
26
|
+
require require_file.to_s
|
27
|
+
raise(Thor::Error, "ERROR: class #{api_name} isn't defined!") unless defined?(api_name)
|
28
|
+
api = Api.new(api_name.constantize)
|
29
|
+
|
30
|
+
# export grape API
|
31
|
+
exporter = Exporter.new(export_path)
|
32
|
+
exporter.export(api)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.banner(command, namespace = nil, subcommand = false)
|
36
|
+
result = "#{basename} #{command.usage}"
|
37
|
+
if namespace != false and command.name == "export"
|
38
|
+
result += "\n\nArguments:\n"
|
39
|
+
result += " <api_name> # Constant name of your Grape API, e.g. MyApp::Api\n"
|
40
|
+
result += " <export_path> # Directory / path where the markdown documentation will be generated in\n"
|
41
|
+
end
|
42
|
+
result
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module GrapeDocs
|
2
|
+
class Endpoint
|
3
|
+
attr_reader :title, :detail, :path, :url, :params, :method, :model, :response
|
4
|
+
|
5
|
+
def initialize(api, endpoint)
|
6
|
+
options = endpoint.options[:route_options]
|
7
|
+
@title = options[:description] || endpoint.options[:path].first
|
8
|
+
@detail = options[:detail]
|
9
|
+
parent_path = File.join(endpoint.inheritable_setting.namespace_stackable[:mount_path])
|
10
|
+
@path = File.join(parent_path, endpoint.options[:path].first.to_s)
|
11
|
+
@url = File.join(GrapeDocs.config[:api_host], @path)
|
12
|
+
@params = options[:params].map { |p| p[1].merge(name: p[0]) }
|
13
|
+
@method = endpoint.options[:method].first
|
14
|
+
if options[:entity]
|
15
|
+
@model = options[:entity].documentation.map { |p| p[1].merge(name: p[0]) }
|
16
|
+
@response = build_response(@model)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def build_response(fields)
|
23
|
+
result = {}
|
24
|
+
fields.each do |field|
|
25
|
+
result[field[:name]] = field[:example]
|
26
|
+
end
|
27
|
+
result
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module GrapeDocs
|
2
|
+
class Exporter
|
3
|
+
attr_reader :root, :template, :api
|
4
|
+
|
5
|
+
def initialize(export_path)
|
6
|
+
@root = Workspace.dir(File.expand_path(export_path)).clean
|
7
|
+
|
8
|
+
# load template
|
9
|
+
filename = "#{GrapeDocs.config[:template]}.md.erb"
|
10
|
+
current_dir = Workspace.dir(Dir.pwd)
|
11
|
+
template_file = current_dir.file(filename)
|
12
|
+
unless template_file.exists?
|
13
|
+
spec = Gem::Specification.find_by_name("grape-docs")
|
14
|
+
assets_dir = Workspace::Dir.new(spec.gem_dir).dir("assets")
|
15
|
+
template_file = assets_dir.file(filename)
|
16
|
+
unless template_file.exists?
|
17
|
+
template_file = assets_dir.file("default.md.erb")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
@template = ERB.new(template_file.read, nil, "%")
|
21
|
+
end
|
22
|
+
|
23
|
+
def export(api)
|
24
|
+
@api = api
|
25
|
+
result = template.result(binding).gsub(/\n\n\n/, "\n\n")
|
26
|
+
root.file("#{api.path}.md").write(result)
|
27
|
+
api.children.each do |child|
|
28
|
+
export(child)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def table(params, *fields, &block)
|
33
|
+
params.each do |param|
|
34
|
+
yield param if block_given?
|
35
|
+
end
|
36
|
+
rows = []
|
37
|
+
rows.push(fields.map { |f| f.to_s.titlecase })
|
38
|
+
params.each do |param|
|
39
|
+
rows.push(fields.map { |f| param[f]&.to_s || "-" })
|
40
|
+
end
|
41
|
+
seperator = []
|
42
|
+
fields.each_with_index do |field, index|
|
43
|
+
field_max = rows.map { |row| row[index] }.max_by(&:length).length
|
44
|
+
seperator.push(":#{'-' * (field_max - 1)}")
|
45
|
+
rows.each_with_index do |row, i|
|
46
|
+
rows[i][index] = rows[i][index] + " " * (field_max - rows[i][index].length)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
rows.insert(1, seperator)
|
50
|
+
rows.map { |row| "| #{row.join(' | ')} |" }.join("\n")
|
51
|
+
end
|
52
|
+
|
53
|
+
def json(data)
|
54
|
+
"```json\n#{JSON.pretty_generate(data)}\n```\n"
|
55
|
+
end
|
56
|
+
|
57
|
+
def document_url(target)
|
58
|
+
path = target.path.sub(%r{^/}, '')
|
59
|
+
"#{path}.md"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: grape-docs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tobias Strebitzer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.3.0
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.3.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: thor
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0.2'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.2'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: workspace
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: activesupport
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '4.0'
|
68
|
+
- - "<"
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '6.0'
|
71
|
+
type: :runtime
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '4.0'
|
78
|
+
- - "<"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '6.0'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: pry
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0.10'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0.10'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: rubocop
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - "~>"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0.49'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - "~>"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0.49'
|
109
|
+
description: grape-docs automagically generates documentation for your Grape API in
|
110
|
+
various formats.
|
111
|
+
email:
|
112
|
+
- tobias.strebitzer@magloft.com
|
113
|
+
executables:
|
114
|
+
- grape-docs
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- README.md
|
119
|
+
- bin/grape-docs
|
120
|
+
- lib/grape_docs.rb
|
121
|
+
- lib/grape_docs/api.rb
|
122
|
+
- lib/grape_docs/command.rb
|
123
|
+
- lib/grape_docs/endpoint.rb
|
124
|
+
- lib/grape_docs/exporter.rb
|
125
|
+
- lib/grape_docs/version.rb
|
126
|
+
homepage: https://github.com/magloft/grape-docs
|
127
|
+
licenses:
|
128
|
+
- BSD-3-Clause
|
129
|
+
metadata: {}
|
130
|
+
post_install_message:
|
131
|
+
rdoc_options: []
|
132
|
+
require_paths:
|
133
|
+
- lib
|
134
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.0'
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - "~>"
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '2.4'
|
144
|
+
requirements: []
|
145
|
+
rubyforge_project:
|
146
|
+
rubygems_version: 2.6.10
|
147
|
+
signing_key:
|
148
|
+
specification_version: 4
|
149
|
+
summary: Automatically generate documentation from grape API
|
150
|
+
test_files: []
|