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 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: []