grape-docs 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ | ![default](http://cdn.magloft.com/marketing/gems/grape-docs/default.png) | ![gitbook](http://cdn.magloft.com/marketing/gems/grape-docs/gitbook.png) |
51
+
52
+ ## License
53
+
54
+ grape-docs is available under an MIT-style license.
data/bin/grape-docs ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'grape_docs/command'
3
+ GrapeDocs::Command.start
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
@@ -0,0 +1,3 @@
1
+ module GrapeDocs
2
+ VERSION = "1.0.0"
3
+ 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: []