betterdocs 0.6.6 → 0.8.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 +4 -4
- data/.gitignore +1 -0
- data/.semaphore/semaphore.yml +26 -0
- data/.tool-versions +1 -0
- data/.vscode/settings.json +6 -0
- data/README.md +4 -4
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/betterdocs.gemspec +21 -32
- data/lib/betterdocs.rb +1 -0
- data/lib/betterdocs/dsl/json_params/param.rb +3 -3
- data/lib/betterdocs/dsl/json_type_mapper.rb +1 -1
- data/lib/betterdocs/dsl/result/property.rb +3 -1
- data/lib/betterdocs/generator/swagger.rb +405 -0
- data/lib/betterdocs/generator/swagger_static/index.html +66 -0
- data/lib/betterdocs/global.rb +44 -8
- data/lib/betterdocs/representer.rb +1 -1
- data/lib/betterdocs/result_representer.rb +1 -1
- data/lib/betterdocs/tasks/doc.rake +25 -18
- data/lib/betterdocs/version.rb +1 -1
- metadata +16 -12
- data/.travis.yml +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7324105b58e4926bdbcec0e372efda88e523c1c31fb4f0181e9d4cebc94b135c
|
4
|
+
data.tar.gz: 6926a2ea9814cae5e763113badf138104f2fd9ae250c57e9cc8a16fb6eb18d43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccaab04fbb9dfc351d79b9b722d1430c1a8afc5007f3f8bfd68d2d7d1c06ab4d26cf843e745750d1eb805b3d83122fb6b48597a8c1a3bc127fee5bc95e43443e
|
7
|
+
data.tar.gz: 67968de292f5c9e0d17b0d2669d72ca75f1e6d709ea219de4f36beab3b99e14452dfa626ff4cb0fe6222419ba99e19f3be4f4765242dbd8d9f0622839d150cf9
|
data/.gitignore
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
version: v1.0
|
2
|
+
name: Betterdocs pipeline
|
3
|
+
agent:
|
4
|
+
machine:
|
5
|
+
type: e1-standard-2
|
6
|
+
os_image: ubuntu1804
|
7
|
+
|
8
|
+
blocks:
|
9
|
+
- name: "Unit Tests"
|
10
|
+
task:
|
11
|
+
env_vars:
|
12
|
+
# Matches the configuration used in sem-service
|
13
|
+
- name: RAILS_ENV
|
14
|
+
value: test
|
15
|
+
jobs:
|
16
|
+
- name: RSpec
|
17
|
+
commands:
|
18
|
+
- checkout
|
19
|
+
|
20
|
+
# Setup ruby
|
21
|
+
- sem-version ruby $(awk '/^ruby/ { print $2 }' .tool-versions)
|
22
|
+
|
23
|
+
# Setup gems
|
24
|
+
- bundle config set path 'vendor/bundle'
|
25
|
+
- bundle install
|
26
|
+
- bundle exec rake spec
|
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 3.0.1
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Betterdocs API Documentation
|
|
6
6
|
DESCRIPTION
|
7
7
|
-----------
|
8
8
|
|
9
|
-
This library can be used to document a
|
9
|
+
This library can be used to document a Rails-based API.
|
10
10
|
|
11
11
|
LICENSE
|
12
12
|
-------
|
@@ -40,12 +40,12 @@ This api generator requires that you follow the [representer pattern](http://nic
|
|
40
40
|
end
|
41
41
|
|
42
42
|
response do
|
43
|
-
generate_fake_result_with_representer
|
43
|
+
generate_fake_result_with_representer
|
44
44
|
end
|
45
45
|
end
|
46
46
|
# :nocov:
|
47
47
|
def index
|
48
|
-
render json: real_result_with_representer
|
48
|
+
render json: real_result_with_representer
|
49
49
|
end
|
50
50
|
|
51
51
|
# :nocov: Documentation
|
@@ -68,7 +68,7 @@ This api generator requires that you follow the [representer pattern](http://nic
|
|
68
68
|
end
|
69
69
|
# :nocov:
|
70
70
|
def show
|
71
|
-
render json: real_result_with_representer
|
71
|
+
render json: real_result_with_representer
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
data/Rakefile
CHANGED
@@ -12,12 +12,12 @@ GemHadar do
|
|
12
12
|
test_dir 'spec'
|
13
13
|
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', 'coverage', '.rvmrc',
|
14
14
|
'.ruby-version', '.AppleDouble', 'tags', '.DS_Store', '.utilsrc',
|
15
|
-
'.bundle', '.byebug_history', 'errors.lst', '.yardoc'
|
15
|
+
'.bundle', '.byebug_history', 'errors.lst', '.yardoc', '.history'
|
16
16
|
readme 'README.md'
|
17
17
|
title "#{name.camelize}"
|
18
18
|
|
19
19
|
dependency 'tins', '~>1.3', '>=1.3.5'
|
20
|
-
dependency 'rails', '>=3', '<
|
20
|
+
dependency 'rails', '>=3', '<7'
|
21
21
|
dependency 'term-ansicolor', '~>1.3'
|
22
22
|
dependency 'complex_config', '~>0.5'
|
23
23
|
dependency 'infobar'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
data/betterdocs.gemspec
CHANGED
@@ -1,57 +1,46 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: betterdocs 0.
|
2
|
+
# stub: betterdocs 0.8.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "betterdocs".freeze
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "0.8.0"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
10
10
|
s.authors = ["betterplace Developers".freeze]
|
11
|
-
s.date = "
|
11
|
+
s.date = "2021-07-07"
|
12
12
|
s.description = "This library provides tools to generate API documention for a web site's REST-ful JSON API.".freeze
|
13
13
|
s.email = "developers@betterplace.org".freeze
|
14
|
-
s.extra_rdoc_files = ["README.md".freeze, "lib/betterdocs.rb".freeze, "lib/betterdocs/controller_collector.rb".freeze, "lib/betterdocs/dsl.rb".freeze, "lib/betterdocs/dsl/common.rb".freeze, "lib/betterdocs/dsl/controller.rb".freeze, "lib/betterdocs/dsl/controller/action.rb".freeze, "lib/betterdocs/dsl/controller/action/param.rb".freeze, "lib/betterdocs/dsl/controller/action/response.rb".freeze, "lib/betterdocs/dsl/controller/controller.rb".freeze, "lib/betterdocs/dsl/controller/controller_base.rb".freeze, "lib/betterdocs/dsl/json_params.rb".freeze, "lib/betterdocs/dsl/json_params/param.rb".freeze, "lib/betterdocs/dsl/json_type_mapper.rb".freeze, "lib/betterdocs/dsl/naming.rb".freeze, "lib/betterdocs/dsl/representer.rb".freeze, "lib/betterdocs/dsl/result.rb".freeze, "lib/betterdocs/dsl/result/collection_property.rb".freeze, "lib/betterdocs/dsl/result/link.rb".freeze, "lib/betterdocs/dsl/result/property.rb".freeze, "lib/betterdocs/generator/config_shortcuts.rb".freeze, "lib/betterdocs/generator/markdown.rb".freeze, "lib/betterdocs/global.rb".freeze, "lib/betterdocs/json_params_representer.rb".freeze, "lib/betterdocs/json_params_representer_collector.rb".freeze, "lib/betterdocs/json_time_with_zone.rb".freeze, "lib/betterdocs/mix_into_controller.rb".freeze, "lib/betterdocs/railtie.rb".freeze, "lib/betterdocs/rake_tasks.rb".freeze, "lib/betterdocs/representer.rb".freeze, "lib/betterdocs/result_representer.rb".freeze, "lib/betterdocs/result_representer_collector.rb".freeze, "lib/betterdocs/sanitizer.rb".freeze, "lib/betterdocs/section.rb".freeze, "lib/betterdocs/version.rb".freeze]
|
15
|
-
s.files = [".codeclimate.yml".freeze, ".gitignore".freeze, ".rspec".freeze, ".
|
14
|
+
s.extra_rdoc_files = ["README.md".freeze, "lib/betterdocs.rb".freeze, "lib/betterdocs/controller_collector.rb".freeze, "lib/betterdocs/dsl.rb".freeze, "lib/betterdocs/dsl/common.rb".freeze, "lib/betterdocs/dsl/controller.rb".freeze, "lib/betterdocs/dsl/controller/action.rb".freeze, "lib/betterdocs/dsl/controller/action/param.rb".freeze, "lib/betterdocs/dsl/controller/action/response.rb".freeze, "lib/betterdocs/dsl/controller/controller.rb".freeze, "lib/betterdocs/dsl/controller/controller_base.rb".freeze, "lib/betterdocs/dsl/json_params.rb".freeze, "lib/betterdocs/dsl/json_params/param.rb".freeze, "lib/betterdocs/dsl/json_type_mapper.rb".freeze, "lib/betterdocs/dsl/naming.rb".freeze, "lib/betterdocs/dsl/representer.rb".freeze, "lib/betterdocs/dsl/result.rb".freeze, "lib/betterdocs/dsl/result/collection_property.rb".freeze, "lib/betterdocs/dsl/result/link.rb".freeze, "lib/betterdocs/dsl/result/property.rb".freeze, "lib/betterdocs/generator/config_shortcuts.rb".freeze, "lib/betterdocs/generator/markdown.rb".freeze, "lib/betterdocs/generator/swagger.rb".freeze, "lib/betterdocs/global.rb".freeze, "lib/betterdocs/json_params_representer.rb".freeze, "lib/betterdocs/json_params_representer_collector.rb".freeze, "lib/betterdocs/json_time_with_zone.rb".freeze, "lib/betterdocs/mix_into_controller.rb".freeze, "lib/betterdocs/railtie.rb".freeze, "lib/betterdocs/rake_tasks.rb".freeze, "lib/betterdocs/representer.rb".freeze, "lib/betterdocs/result_representer.rb".freeze, "lib/betterdocs/result_representer_collector.rb".freeze, "lib/betterdocs/sanitizer.rb".freeze, "lib/betterdocs/section.rb".freeze, "lib/betterdocs/version.rb".freeze]
|
15
|
+
s.files = [".codeclimate.yml".freeze, ".gitignore".freeze, ".rspec".freeze, ".semaphore/semaphore.yml".freeze, ".tool-versions".freeze, ".vscode/settings.json".freeze, "COPYING".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "betterdocs.gemspec".freeze, "lib/betterdocs.rb".freeze, "lib/betterdocs/controller_collector.rb".freeze, "lib/betterdocs/dsl.rb".freeze, "lib/betterdocs/dsl/common.rb".freeze, "lib/betterdocs/dsl/controller.rb".freeze, "lib/betterdocs/dsl/controller/action.rb".freeze, "lib/betterdocs/dsl/controller/action/param.rb".freeze, "lib/betterdocs/dsl/controller/action/response.rb".freeze, "lib/betterdocs/dsl/controller/controller.rb".freeze, "lib/betterdocs/dsl/controller/controller_base.rb".freeze, "lib/betterdocs/dsl/json_params.rb".freeze, "lib/betterdocs/dsl/json_params/param.rb".freeze, "lib/betterdocs/dsl/json_type_mapper.rb".freeze, "lib/betterdocs/dsl/naming.rb".freeze, "lib/betterdocs/dsl/representer.rb".freeze, "lib/betterdocs/dsl/result.rb".freeze, "lib/betterdocs/dsl/result/collection_property.rb".freeze, "lib/betterdocs/dsl/result/link.rb".freeze, "lib/betterdocs/dsl/result/property.rb".freeze, "lib/betterdocs/generator/config_shortcuts.rb".freeze, "lib/betterdocs/generator/markdown.rb".freeze, "lib/betterdocs/generator/markdown/templates/README.md.erb".freeze, "lib/betterdocs/generator/markdown/templates/section.md.erb".freeze, "lib/betterdocs/generator/swagger.rb".freeze, "lib/betterdocs/generator/swagger_static/index.html".freeze, "lib/betterdocs/global.rb".freeze, "lib/betterdocs/json_params_representer.rb".freeze, "lib/betterdocs/json_params_representer_collector.rb".freeze, "lib/betterdocs/json_time_with_zone.rb".freeze, "lib/betterdocs/mix_into_controller.rb".freeze, "lib/betterdocs/railtie.rb".freeze, "lib/betterdocs/rake_tasks.rb".freeze, "lib/betterdocs/representer.rb".freeze, "lib/betterdocs/result_representer.rb".freeze, "lib/betterdocs/result_representer_collector.rb".freeze, "lib/betterdocs/sanitizer.rb".freeze, "lib/betterdocs/section.rb".freeze, "lib/betterdocs/tasks/doc.rake".freeze, "lib/betterdocs/version.rb".freeze, "spec/assets/app/assets/images/logos/logo.png".freeze, "spec/assets/app/controllers/api/foos_controller.rb".freeze, "spec/assets/app/views/api_v4/documentation/assets/CHANGELOG.md".freeze, "spec/assets/config/betterdocs.yml".freeze, "spec/betterdocs/dsl/controller/action/param_spec.rb".freeze, "spec/betterdocs/dsl/controller/action/response_spec.rb".freeze, "spec/betterdocs/dsl/json_type_mapper_spec.rb".freeze, "spec/betterdocs/dsl/result/collection_property_spec.rb".freeze, "spec/betterdocs/dsl/result/link_spec.rb".freeze, "spec/betterdocs/dsl/result/property_spec.rb".freeze, "spec/betterdocs/generator/markdown_spec.rb".freeze, "spec/betterdocs/global_spec.rb".freeze, "spec/betterdocs/json_params_representer_spec.rb".freeze, "spec/betterdocs/result_representer_spec.rb".freeze, "spec/betterdocs/sanitizer_spec.rb".freeze, "spec/controller_dsl_spec.rb".freeze, "spec/result_representer_dsl_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
16
16
|
s.homepage = "http://github.com/betterplace/betterdocs".freeze
|
17
17
|
s.rdoc_options = ["--title".freeze, "Betterdocs".freeze, "--main".freeze, "README.md".freeze]
|
18
|
-
s.rubygems_version = "2.
|
18
|
+
s.rubygems_version = "3.2.15".freeze
|
19
19
|
s.summary = "Betterplace API documentation library".freeze
|
20
20
|
s.test_files = ["spec/assets/app/controllers/api/foos_controller.rb".freeze, "spec/betterdocs/dsl/controller/action/param_spec.rb".freeze, "spec/betterdocs/dsl/controller/action/response_spec.rb".freeze, "spec/betterdocs/dsl/json_type_mapper_spec.rb".freeze, "spec/betterdocs/dsl/result/collection_property_spec.rb".freeze, "spec/betterdocs/dsl/result/link_spec.rb".freeze, "spec/betterdocs/dsl/result/property_spec.rb".freeze, "spec/betterdocs/generator/markdown_spec.rb".freeze, "spec/betterdocs/global_spec.rb".freeze, "spec/betterdocs/json_params_representer_spec.rb".freeze, "spec/betterdocs/result_representer_spec.rb".freeze, "spec/betterdocs/sanitizer_spec.rb".freeze, "spec/controller_dsl_spec.rb".freeze, "spec/result_representer_dsl_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
21
21
|
|
22
22
|
if s.respond_to? :specification_version then
|
23
23
|
s.specification_version = 4
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
else
|
37
|
-
s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.9.1"])
|
38
|
-
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
39
|
-
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
40
|
-
s.add_dependency(%q<rspec>.freeze, [">= 0"])
|
41
|
-
s.add_dependency(%q<tins>.freeze, [">= 1.3.5", "~> 1.3"])
|
42
|
-
s.add_dependency(%q<rails>.freeze, ["< 6", ">= 3"])
|
43
|
-
s.add_dependency(%q<term-ansicolor>.freeze, ["~> 1.3"])
|
44
|
-
s.add_dependency(%q<complex_config>.freeze, ["~> 0.5"])
|
45
|
-
s.add_dependency(%q<infobar>.freeze, [">= 0"])
|
46
|
-
s.add_dependency(%q<mize>.freeze, [">= 0"])
|
47
|
-
end
|
26
|
+
if s.respond_to? :add_runtime_dependency then
|
27
|
+
s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.11.0"])
|
28
|
+
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
|
29
|
+
s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
|
30
|
+
s.add_development_dependency(%q<rspec>.freeze, [">= 0"])
|
31
|
+
s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.3", ">= 1.3.5"])
|
32
|
+
s.add_runtime_dependency(%q<rails>.freeze, [">= 3", "< 7"])
|
33
|
+
s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.3"])
|
34
|
+
s.add_runtime_dependency(%q<complex_config>.freeze, ["~> 0.5"])
|
35
|
+
s.add_runtime_dependency(%q<infobar>.freeze, [">= 0"])
|
36
|
+
s.add_runtime_dependency(%q<mize>.freeze, [">= 0"])
|
48
37
|
else
|
49
|
-
s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.
|
38
|
+
s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.11.0"])
|
50
39
|
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
51
40
|
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
52
41
|
s.add_dependency(%q<rspec>.freeze, [">= 0"])
|
53
|
-
s.add_dependency(%q<tins>.freeze, ["
|
54
|
-
s.add_dependency(%q<rails>.freeze, ["
|
42
|
+
s.add_dependency(%q<tins>.freeze, ["~> 1.3", ">= 1.3.5"])
|
43
|
+
s.add_dependency(%q<rails>.freeze, [">= 3", "< 7"])
|
55
44
|
s.add_dependency(%q<term-ansicolor>.freeze, ["~> 1.3"])
|
56
45
|
s.add_dependency(%q<complex_config>.freeze, ["~> 0.5"])
|
57
46
|
s.add_dependency(%q<infobar>.freeze, [">= 0"])
|
data/lib/betterdocs.rb
CHANGED
@@ -26,6 +26,7 @@ require 'betterdocs/section'
|
|
26
26
|
require 'betterdocs/mix_into_controller'
|
27
27
|
require 'betterdocs/generator/config_shortcuts'
|
28
28
|
require 'betterdocs/generator/markdown'
|
29
|
+
require 'betterdocs/generator/swagger'
|
29
30
|
require 'betterdocs/rake_tasks'
|
30
31
|
require 'betterdocs/json_time_with_zone'
|
31
32
|
defined? Rails and require 'betterdocs/railtie'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/time_with_zone'
|
2
|
+
|
1
3
|
require 'betterdocs/dsl/naming'
|
2
4
|
|
3
5
|
class Betterdocs::Dsl::JsonParams::Param < Betterdocs::Dsl::Representer
|
@@ -25,9 +27,7 @@ class Betterdocs::Dsl::JsonParams::Param < Betterdocs::Dsl::Representer
|
|
25
27
|
|
26
28
|
def compute_value(object)
|
27
29
|
value = object.__send__(name)
|
28
|
-
|
29
|
-
value.extend Betterdocs::JsonTimeWithZone
|
30
|
-
end
|
30
|
+
value.respond_to?(:iso8601) and value.extend Betterdocs::JsonTimeWithZone
|
31
31
|
value
|
32
32
|
end
|
33
33
|
|
@@ -13,7 +13,7 @@ module Betterdocs::Dsl::JsonTypeMapper
|
|
13
13
|
String => 'string',
|
14
14
|
}.find { |match_class, json_type|
|
15
15
|
match_class >= klass and break json_type
|
16
|
-
}
|
16
|
+
} or raise TypeError, "Invalid type #{klass} encountered. Use a type that can be mapped to JSON instead."
|
17
17
|
end
|
18
18
|
|
19
19
|
def map_types(types)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/time_with_zone'
|
2
|
+
|
1
3
|
require 'betterdocs/dsl/representer'
|
2
4
|
require 'betterdocs/dsl/common'
|
3
5
|
require 'betterdocs/dsl/naming'
|
@@ -46,7 +48,7 @@ class Betterdocs::Dsl::Result::Property < Betterdocs::Dsl::Representer
|
|
46
48
|
value.nil? and return
|
47
49
|
if represent_with
|
48
50
|
represent_with.hashify(value)
|
49
|
-
elsif
|
51
|
+
elsif value.respond_to?(:iso8601)
|
50
52
|
value.extend Betterdocs::JsonTimeWithZone
|
51
53
|
else
|
52
54
|
sanitizer.sanitize(value)
|
@@ -0,0 +1,405 @@
|
|
1
|
+
require 'infobar'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'term/ansicolor'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Betterdocs
|
7
|
+
module Generator
|
8
|
+
class Swagger
|
9
|
+
include ::Betterdocs::Generator::ConfigShortcuts
|
10
|
+
include Term::ANSIColor
|
11
|
+
include FileUtils
|
12
|
+
|
13
|
+
def initialize(only: nil)
|
14
|
+
only and @only = Regexp.new(only)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
if dir = config.swagger_output_directory.full?
|
19
|
+
generate_to dir
|
20
|
+
else
|
21
|
+
raise 'Specify an output_directory in your configuration!'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_to(dirname)
|
26
|
+
map = { openapi: '3.0.2', paths: {}, components: { schemas: {} } }
|
27
|
+
add_error_envelope_schema(map[:components][:schemas])
|
28
|
+
configure_for_creation
|
29
|
+
prepare_dir(dirname)
|
30
|
+
add_global_info(map)
|
31
|
+
create_sections(map)
|
32
|
+
create_swagger(map, dirname)
|
33
|
+
create_assets
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def configure_for_creation
|
38
|
+
infobar.puts color(40, "Setting asset_host to #{Betterdocs::Global.asset_host.inspect}.")
|
39
|
+
Betterdocs.rails.configuration.action_controller.asset_host = Betterdocs::Global.asset_host
|
40
|
+
options = {
|
41
|
+
host: Betterdocs::Global.api_host,
|
42
|
+
protocol: Betterdocs::Global.api_protocol,
|
43
|
+
}
|
44
|
+
infobar.puts color(40, "Setting default_url_options to #{options.inspect}.")
|
45
|
+
Betterdocs.rails.application.routes.default_url_options = options
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_global_info(map)
|
50
|
+
slugs = get_request_url_slugs(sections.values.first.first.request)
|
51
|
+
map[:info] = { title: project_name, version: slugs[:ver] }
|
52
|
+
map[:servers] =
|
53
|
+
[{ url: "#{slugs[:protocol]}://#{[slugs[:host], slugs[:lang], "api_#{slugs[:ver]}"].join('/')}" }]
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_sections(map)
|
57
|
+
Infobar(total: sections.size)
|
58
|
+
sections.values.each do |section|
|
59
|
+
infobar.progress(
|
60
|
+
message: " Section #{section.name.to_s.inspect} %c/%t in %te ETA %e @%E ",
|
61
|
+
force: true,
|
62
|
+
)
|
63
|
+
@only =~ section.name or next if @only
|
64
|
+
|
65
|
+
map = get_section_data(map, section)
|
66
|
+
end
|
67
|
+
infobar.finish message: ' %t sections created in %te, completed @%E '
|
68
|
+
infobar.newline
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_assets
|
73
|
+
Infobar(total: config.swagger_assets.size)
|
74
|
+
config.each_swagger_asset do |src, dst|
|
75
|
+
infobar.progress(
|
76
|
+
message: " Asset #{File.basename(src).inspect} %c/%t in %te ETA %e @%E ",
|
77
|
+
force: true,
|
78
|
+
)
|
79
|
+
mkdir_p File.dirname(dst)
|
80
|
+
cp Betterdocs.rails.root.join(src), dst
|
81
|
+
end
|
82
|
+
infobar.finish message: ' %t assets created in %te, completed @%E '
|
83
|
+
infobar.newline
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_swagger(map, dirname)
|
88
|
+
name = 'swagger.json'
|
89
|
+
cd dirname do
|
90
|
+
infobar.puts color(40, 'Creating swagger.')
|
91
|
+
json = JSON.pretty_generate(map)
|
92
|
+
render_to(name, json)
|
93
|
+
end
|
94
|
+
self
|
95
|
+
end
|
96
|
+
|
97
|
+
def fail_while_rendering(exception)
|
98
|
+
message = color(
|
99
|
+
231,
|
100
|
+
on_color(124, " *** ERROR #{exception.class}: #{exception.message.inspect} ***")
|
101
|
+
)
|
102
|
+
infobar.puts message
|
103
|
+
exit 1
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_param(hash, name, param_in, required = false, type = nil, description = '', schema = nil)
|
107
|
+
hash[:parameters] ||= []
|
108
|
+
p = { in: param_in, required: required, description: description, name: name }
|
109
|
+
p[:schema] = { type: type } unless type.nil?
|
110
|
+
p[:schema] = schema unless schema.nil?
|
111
|
+
hash[:parameters].push(p)
|
112
|
+
hash
|
113
|
+
end
|
114
|
+
|
115
|
+
def add_default_list_params(hash)
|
116
|
+
p = add_param(hash, 'page', 'query', false, 'integer')
|
117
|
+
add_param(p, 'per_page', 'query', false, 'integer')
|
118
|
+
end
|
119
|
+
|
120
|
+
def get_list_response_wrapper_schema
|
121
|
+
{
|
122
|
+
type: 'object',
|
123
|
+
properties: {
|
124
|
+
total_entries: { type: 'integer' },
|
125
|
+
offset: { type: 'integer' },
|
126
|
+
total_pages: { type: 'integer' },
|
127
|
+
current_page: { type: 'integer' },
|
128
|
+
per_page: { type: 'integer' },
|
129
|
+
},
|
130
|
+
required: %w[total_entries offset current_page per_page total_pages data],
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
def get_param_value_type(value)
|
135
|
+
case value
|
136
|
+
when String then 'string'
|
137
|
+
when Integer then 'integer'
|
138
|
+
when TrueClass, FalseClass then 'boolean'
|
139
|
+
when Float then 'number'
|
140
|
+
when Array then 'array'
|
141
|
+
else 'object'
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def get_path_param_slug_type(slug)
|
146
|
+
return 'integer' if /\A[0-9]+\z/.match(slug)
|
147
|
+
|
148
|
+
'string'
|
149
|
+
end
|
150
|
+
|
151
|
+
def add_error_envelope_schema(definitions)
|
152
|
+
definitions['ErrorEnvelope'] = {
|
153
|
+
type: 'object',
|
154
|
+
properties: {
|
155
|
+
name: { type: 'string' },
|
156
|
+
status: { type: 'string' },
|
157
|
+
status_code: { type: 'integer' },
|
158
|
+
reason: { type: 'string' },
|
159
|
+
backtrace: { type: 'array', items: { type: 'string' } },
|
160
|
+
message: { type: 'string' },
|
161
|
+
errors: { type: 'object' },
|
162
|
+
links: { type: 'array', items: { type: 'string' } },
|
163
|
+
},
|
164
|
+
required: %w[name status status_code reason backtrace message links],
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
def get_error_envelope_schema_ref
|
169
|
+
{ schema: get_schema_ref('ErrorEnvelope') }
|
170
|
+
end
|
171
|
+
|
172
|
+
def get_request_url_slugs(request)
|
173
|
+
slugs = %r{
|
174
|
+
(?<method>GET|POST|PUT|DELETE|OPTIONS)\s+
|
175
|
+
(?<protocol>https?)://
|
176
|
+
(?<host>[a-z.]+)/
|
177
|
+
(?<lang>[a-z]{2})/api_
|
178
|
+
(?<ver>v[0-9]+)/
|
179
|
+
(?<path>[\w/]+\.json?)
|
180
|
+
}x.match(request).named_captures.transform_keys(&:to_sym)
|
181
|
+
slugs[:params] = []
|
182
|
+
split = slugs[:path].split('/')
|
183
|
+
path_cmp = split.map.with_index do |cmp, i|
|
184
|
+
unless i.even?
|
185
|
+
suffix = cmp['.json'] || ''
|
186
|
+
name = "#{split[i - 1]}_id"
|
187
|
+
cmp = "{#{name}}#{suffix}"
|
188
|
+
param = { name: name, type: get_path_param_slug_type(cmp.gsub('.json', '')) }
|
189
|
+
slugs[:params].push(param)
|
190
|
+
end
|
191
|
+
cmp
|
192
|
+
end
|
193
|
+
slugs[:method] = slugs[:method].downcase
|
194
|
+
slugs[:path] = "/#{path_cmp.join('/')}"
|
195
|
+
slugs
|
196
|
+
end
|
197
|
+
|
198
|
+
def get_request_definition(params)
|
199
|
+
schema = { type: 'object', properties: {}, required: [] }
|
200
|
+
params.each do |param|
|
201
|
+
schema[:properties][param.name] = get_schema(param.types, nil, param.description)
|
202
|
+
schema[:required].push(param.name) if param.required == true || param.required == 'yes'
|
203
|
+
end
|
204
|
+
schema
|
205
|
+
end
|
206
|
+
|
207
|
+
def get_name(title)
|
208
|
+
/([\w\s]+)/.match(title)[1]
|
209
|
+
end
|
210
|
+
|
211
|
+
def get_type(types)
|
212
|
+
type = types
|
213
|
+
nullable = false
|
214
|
+
if types.instance_of? Array
|
215
|
+
case types.length
|
216
|
+
when 0
|
217
|
+
type = nil
|
218
|
+
when 1
|
219
|
+
type = types[0]
|
220
|
+
else
|
221
|
+
types.each do |t|
|
222
|
+
if t == 'null'
|
223
|
+
nullable = true
|
224
|
+
else
|
225
|
+
type = t
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
unless %w[integer number string boolean array object].include?(type)
|
231
|
+
puts "Warning: invalid type #{type || 'nil'}"
|
232
|
+
end
|
233
|
+
[type, nullable]
|
234
|
+
end
|
235
|
+
|
236
|
+
def get_deprecated_from_description(description)
|
237
|
+
description.include?('DEPRECATED')
|
238
|
+
end
|
239
|
+
|
240
|
+
def get_schema(types, sub_cls, description)
|
241
|
+
type, nullable = get_type(types)
|
242
|
+
deprecated = get_deprecated_from_description(description)
|
243
|
+
res = { description: description, type: type, nullable: nullable, deprecated: deprecated }
|
244
|
+
case type
|
245
|
+
when 'array'
|
246
|
+
items = { type: 'string' }
|
247
|
+
items = get_schema_ref(sub_cls) if sub_cls
|
248
|
+
res[:items] = items
|
249
|
+
when 'object'
|
250
|
+
res = get_schema_ref(sub_cls) if sub_cls
|
251
|
+
res[:description] = description
|
252
|
+
res[:deprecated] = deprecated
|
253
|
+
end
|
254
|
+
res[:nullable] = true if nullable
|
255
|
+
res
|
256
|
+
end
|
257
|
+
|
258
|
+
def get_dto_name(representer)
|
259
|
+
representer&.name&.demodulize
|
260
|
+
end
|
261
|
+
|
262
|
+
def add_links_definition(definitions, cls, value)
|
263
|
+
definition = initialise_definition(definitions, cls)
|
264
|
+
definition[:properties][:links] ||= {
|
265
|
+
type: 'array',
|
266
|
+
nullable: false,
|
267
|
+
items: {
|
268
|
+
type: 'object',
|
269
|
+
properties: {
|
270
|
+
rel: { type: 'string', enum: [] },
|
271
|
+
href: { type: 'string' },
|
272
|
+
},
|
273
|
+
required: %w[rel href],
|
274
|
+
},
|
275
|
+
}
|
276
|
+
enum = definition[:properties][:links][:items][:properties][:rel][:enum]
|
277
|
+
enum.push(value) unless enum.include?(value)
|
278
|
+
end
|
279
|
+
|
280
|
+
def initialise_definition(definitions, cls)
|
281
|
+
definitions[cls] ||= { type: 'object', properties: {} }
|
282
|
+
end
|
283
|
+
|
284
|
+
def add_response_schema(definitions, response)
|
285
|
+
return nil unless response.full?
|
286
|
+
|
287
|
+
subs = {}
|
288
|
+
resp_cls = get_dto_name(response.representer)
|
289
|
+
(response.full?(:properties) || []).each do |p|
|
290
|
+
subs[p.full_name] = p.sub_representer? if p.sub_representer?
|
291
|
+
sub_cls = get_dto_name(subs[p.nesting_name])
|
292
|
+
cls = sub_cls || resp_cls
|
293
|
+
definition = initialise_definition(definitions, cls)
|
294
|
+
definition[:properties][p.public_name] = get_schema(p.types, get_dto_name(p.sub_representer?), p.description)
|
295
|
+
end
|
296
|
+
(response.full?(:links) || []).each do |l|
|
297
|
+
sub_cls = get_dto_name(subs[l.nesting_name])
|
298
|
+
add_links_definition(definitions, sub_cls || resp_cls, l.public_name)
|
299
|
+
end
|
300
|
+
get_schema_ref(resp_cls)
|
301
|
+
end
|
302
|
+
|
303
|
+
def get_schema_ref(name)
|
304
|
+
{
|
305
|
+
"$ref": "#/components/schemas/#{name}",
|
306
|
+
}
|
307
|
+
end
|
308
|
+
|
309
|
+
def add_required_to_definitions(definitions)
|
310
|
+
definitions.each do |def_key, d|
|
311
|
+
req = d[:properties].select { |_k, v| v.key?(:nullable) }.keys
|
312
|
+
definitions[def_key][:required] = req unless req.empty?
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
def add_body(definitions, params, action, name)
|
317
|
+
if action.json_params.full?
|
318
|
+
payload_name = "#{name.titleize.gsub(/\s/, '')}Request"
|
319
|
+
definitions[payload_name] = get_request_definition(action.json_params.values)
|
320
|
+
params[:requestBody] = wrap_content_object({ schema: get_schema_ref(payload_name) }, "#{name} Request")
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def add_path_params(params, from_path)
|
325
|
+
from_path.each do |param|
|
326
|
+
add_param(params, param[:name], 'path', true, param[:type], param[:name])
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def add_query_params(params, from_query, is_a_list)
|
331
|
+
from_query.each do |param|
|
332
|
+
add_param(params, param.name, 'query', param.required, get_param_value_type(param.value),
|
333
|
+
param.description)
|
334
|
+
end
|
335
|
+
add_default_list_params(params) if is_a_list
|
336
|
+
end
|
337
|
+
|
338
|
+
def wrap_content_object(object, description)
|
339
|
+
{ content: { "application/json": object }, description: description }
|
340
|
+
end
|
341
|
+
|
342
|
+
def add_example(obj, name, example)
|
343
|
+
obj[:examples] ||= {}
|
344
|
+
obj[:examples][name] = { value: example }
|
345
|
+
end
|
346
|
+
|
347
|
+
def get_section_data(map, section)
|
348
|
+
section.each do |action|
|
349
|
+
name = get_name(action.title)
|
350
|
+
p = { description: action.description, summary: name }
|
351
|
+
is_a_list = action.response.data.instance_of?(ApiTools::ResultSet)
|
352
|
+
slugs = get_request_url_slugs(action.request)
|
353
|
+
add_path_params(p, slugs[:params])
|
354
|
+
add_query_params(p, action.params.values, is_a_list)
|
355
|
+
add_body(map[:components][:schemas], p, action, name)
|
356
|
+
item = add_response_schema(map[:components][:schemas], action.response)
|
357
|
+
schema = item
|
358
|
+
if is_a_list
|
359
|
+
list = get_list_response_wrapper_schema
|
360
|
+
list[:properties][:data] = { type: 'array', items: item }
|
361
|
+
schema = list
|
362
|
+
end
|
363
|
+
ok = { schema: schema }
|
364
|
+
unless action.response.nil?
|
365
|
+
add_example(ok, 'example', JSON.parse(JSON.pretty_generate(action.response, quirks_mode: true)))
|
366
|
+
end
|
367
|
+
p[:responses] =
|
368
|
+
{ "200": wrap_content_object(ok, 'OK'),
|
369
|
+
default: wrap_content_object(get_error_envelope_schema_ref, 'Error') }
|
370
|
+
wrapped = {}
|
371
|
+
wrapped = map[slugs[:path]] if map.key?(slugs[:path])
|
372
|
+
wrapped[slugs[:method]] = p
|
373
|
+
map[:paths][slugs[:path]] = wrapped
|
374
|
+
end
|
375
|
+
add_required_to_definitions(map[:components][:schemas])
|
376
|
+
map
|
377
|
+
end
|
378
|
+
|
379
|
+
def render_to(filename, content)
|
380
|
+
File.open(filename, 'w') do |output|
|
381
|
+
output.write(content)
|
382
|
+
end
|
383
|
+
self
|
384
|
+
rescue StandardError => e
|
385
|
+
fail_while_rendering(e)
|
386
|
+
end
|
387
|
+
|
388
|
+
def prepare_dir(dirname)
|
389
|
+
dirname.present? or raise ArgumentError,
|
390
|
+
"#{dirname.inspect} should be an explicite output dirname"
|
391
|
+
begin
|
392
|
+
stat = File.stat(dirname)
|
393
|
+
if stat.directory?
|
394
|
+
rm_rf Dir[dirname.to_s + '/**/*']
|
395
|
+
else
|
396
|
+
raise ArgumentError, "#{dirname.inspect} is not a directory"
|
397
|
+
end
|
398
|
+
rescue Errno::ENOENT
|
399
|
+
end
|
400
|
+
mkdir_p dirname.to_s
|
401
|
+
self
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!-- HTML for static distribution bundle build -->
|
2
|
+
<!DOCTYPE html>
|
3
|
+
<html lang="en">
|
4
|
+
<head>
|
5
|
+
<meta charset="UTF-8" />
|
6
|
+
<title>Swagger UI</title>
|
7
|
+
|
8
|
+
<link
|
9
|
+
rel="stylesheet"
|
10
|
+
href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.8.1/swagger-ui.css"
|
11
|
+
type="text/css"
|
12
|
+
charset="UTF-8"
|
13
|
+
/>
|
14
|
+
<style>
|
15
|
+
html {
|
16
|
+
box-sizing: border-box;
|
17
|
+
overflow: -moz-scrollbars-vertical;
|
18
|
+
overflow-y: scroll;
|
19
|
+
}
|
20
|
+
|
21
|
+
*,
|
22
|
+
*:before,
|
23
|
+
*:after {
|
24
|
+
box-sizing: inherit;
|
25
|
+
}
|
26
|
+
|
27
|
+
body {
|
28
|
+
margin: 0;
|
29
|
+
background: #fafafa;
|
30
|
+
}
|
31
|
+
</style>
|
32
|
+
</head>
|
33
|
+
|
34
|
+
<body>
|
35
|
+
<div id="swagger-ui"></div>
|
36
|
+
|
37
|
+
<script
|
38
|
+
src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.8.1/swagger-ui-bundle.js"
|
39
|
+
charset="UTF-8"
|
40
|
+
></script>
|
41
|
+
<script
|
42
|
+
src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.8.1/swagger-ui-standalone-preset.js"
|
43
|
+
charset="UTF-8"
|
44
|
+
></script>
|
45
|
+
<script>
|
46
|
+
window.onload = function () {
|
47
|
+
fetch("./swagger.json")
|
48
|
+
.then(resp => resp.json())
|
49
|
+
.then(spec => {
|
50
|
+
const ui = SwaggerUIBundle({
|
51
|
+
spec: spec,
|
52
|
+
dom_id: "#swagger-ui",
|
53
|
+
deepLinking: true,
|
54
|
+
presets: [
|
55
|
+
SwaggerUIBundle.presets.apis,
|
56
|
+
SwaggerUIStandalonePreset,
|
57
|
+
],
|
58
|
+
plugins: [SwaggerUIBundle.plugins.DownloadUrl],
|
59
|
+
layout: "BaseLayout",
|
60
|
+
});
|
61
|
+
window.ui = ui;
|
62
|
+
});
|
63
|
+
};
|
64
|
+
</script>
|
65
|
+
</body>
|
66
|
+
</html>
|
data/lib/betterdocs/global.rb
CHANGED
@@ -27,7 +27,7 @@ module Betterdocs
|
|
27
27
|
platform_host host
|
28
28
|
__send__("#{prefix}_host", host)
|
29
29
|
else
|
30
|
-
[
|
30
|
+
[__send__("#{prefix}_protocol"), __send__("#{prefix}_host")].join('://')
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -41,7 +41,7 @@ module Betterdocs
|
|
41
41
|
|
42
42
|
dsl_accessor :api_protocol do platform_protocol end # Protocol the API understands
|
43
43
|
|
44
|
-
dsl_accessor :api_host
|
44
|
+
dsl_accessor :api_host do platform_host end # Hostname of the API (eventuallly with port number)
|
45
45
|
|
46
46
|
def api_url(url = nil)
|
47
47
|
handle_url(:api, url)
|
@@ -55,7 +55,7 @@ module Betterdocs
|
|
55
55
|
handle_url(:asset, url)
|
56
56
|
end
|
57
57
|
|
58
|
-
dsl_accessor :api_default_format,
|
58
|
+
dsl_accessor :api_default_format, 'json'
|
59
59
|
|
60
60
|
def api_base_url
|
61
61
|
"#{api_protocol}://#{api_host}/#{api_prefix}"
|
@@ -65,9 +65,11 @@ module Betterdocs
|
|
65
65
|
{ protocol: api_protocol, host: api_host, format: api_default_format }
|
66
66
|
end
|
67
67
|
|
68
|
-
dsl_accessor :templates_directory
|
68
|
+
dsl_accessor :templates_directory # Template directory, where customised templates live if any exist
|
69
69
|
|
70
|
-
dsl_accessor :output_directory,
|
70
|
+
dsl_accessor :output_directory, 'api_docs' # Output directory, where the api docs are created
|
71
|
+
|
72
|
+
dsl_accessor :swagger_output_directory, 'swagger_docs' # Output directory, where the swagger docs are created
|
71
73
|
|
72
74
|
dsl_accessor :publish_git # URL to the git repo to which the docs are pushed
|
73
75
|
|
@@ -89,6 +91,17 @@ module Betterdocs
|
|
89
91
|
@assets
|
90
92
|
end
|
91
93
|
|
94
|
+
def swagger_assets=(hash)
|
95
|
+
@swagger_assets&.clear
|
96
|
+
swagger_assets(hash)
|
97
|
+
end
|
98
|
+
|
99
|
+
def swagger_assets(hash = nil)
|
100
|
+
@swagger_assets ||= {}
|
101
|
+
hash&.each { |path, to| swagger_asset path, to: to }
|
102
|
+
@swagger_assets
|
103
|
+
end
|
104
|
+
|
92
105
|
# Defines an asset for the file at +path+. If +to+ was given it will be
|
93
106
|
# copied to this path (it includes the basename) below
|
94
107
|
# +templates_directory+ in the output, otherwise it will be copied
|
@@ -100,14 +113,25 @@ module Betterdocs
|
|
100
113
|
elsif to == :root
|
101
114
|
@assets[path.to_s] = to
|
102
115
|
else
|
103
|
-
raise ArgumentError,
|
116
|
+
raise ArgumentError, 'keyword argument to needs to be a string or :root'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def swagger_asset(path, to: :root)
|
121
|
+
@swagger_assets ||= {}
|
122
|
+
if destination = to.ask_and_send(:to_str)
|
123
|
+
@swagger_assets[path.to_s] = destination
|
124
|
+
elsif to == :root
|
125
|
+
@swagger_assets[path.to_s] = to
|
126
|
+
else
|
127
|
+
raise ArgumentError, 'keyword argument to needs to be a string or :root'
|
104
128
|
end
|
105
129
|
end
|
106
130
|
|
107
131
|
# Maps the assets original source path to its destination path in the
|
108
132
|
# output by yielding to every asset's source/destination pair.
|
109
133
|
def each_asset
|
110
|
-
|
134
|
+
assets.each do |(path, destination)|
|
111
135
|
path = path.to_s
|
112
136
|
if destination == :root
|
113
137
|
yield path, File.join(output_directory.to_s, File.basename(path))
|
@@ -117,6 +141,17 @@ module Betterdocs
|
|
117
141
|
end
|
118
142
|
end
|
119
143
|
|
144
|
+
def each_swagger_asset
|
145
|
+
swagger_assets.each do |(path, destination)|
|
146
|
+
path = path.to_s
|
147
|
+
if destination == :root
|
148
|
+
yield path, File.join(swagger_output_directory.to_s, File.basename(path))
|
149
|
+
else
|
150
|
+
yield path, File.join(swagger_output_directory.to_s, destination.to_str)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
120
155
|
def configuration_file
|
121
156
|
cc.betterdocs
|
122
157
|
rescue ComplexConfig::ConfigurationFileMissing
|
@@ -192,7 +227,8 @@ module Betterdocs
|
|
192
227
|
|
193
228
|
def url_for(options = {})
|
194
229
|
Betterdocs.rails.application.routes.url_for(
|
195
|
-
options | Betterdocs::Global.config.api_url_options
|
230
|
+
options | Betterdocs::Global.config.api_url_options
|
231
|
+
)
|
196
232
|
end
|
197
233
|
end
|
198
234
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
namespace :doc do
|
2
|
-
desc
|
3
|
-
task :
|
2
|
+
desc 'Create the API documentation'
|
3
|
+
task api: :'doc:api:sandbox' do
|
4
4
|
Betterdocs::Global.config do |config|
|
5
5
|
Betterdocs::Generator::Markdown.new(only: ENV['ONLY']).generate
|
6
6
|
cd config.output_directory do
|
@@ -15,39 +15,46 @@ namespace :doc do
|
|
15
15
|
|
16
16
|
namespace :api do
|
17
17
|
desc 'Let database transactions run in a sandboxed environment'
|
18
|
-
task :
|
19
|
-
|
18
|
+
task sandbox: %i[doc:set_betterdocs_env environment] do
|
20
19
|
ActiveRecord::Base.connection.begin_db_transaction
|
21
20
|
at_exit do
|
22
|
-
|
21
|
+
ActiveRecord::Base.connection.rollback_db_transaction
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
|
-
desc
|
27
|
-
task :
|
25
|
+
desc 'Create the API swagger documentation'
|
26
|
+
task swagger: :'doc:api:sandbox' do
|
28
27
|
Betterdocs::Global.config do |config|
|
29
|
-
|
28
|
+
Betterdocs::Generator::Swagger.new(only: ENV['ONLY']).generate
|
29
|
+
cd config.swagger_output_directory do
|
30
|
+
File.open('.gitignore', 'w') { |ignore| ignore.puts config.ignore }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Push the newly created API documentation to the remote git repo'
|
36
|
+
task push: :api do
|
37
|
+
Betterdocs::Global.config do |config|
|
38
|
+
config.publish_git or raise 'Configure a git repo as publish_git to publish to'
|
30
39
|
cd config.output_directory do
|
31
|
-
File.directory?('.git') or sh
|
32
|
-
sh
|
40
|
+
File.directory?('.git') or sh 'git init'
|
41
|
+
sh 'git remote rm publish_git || true'
|
33
42
|
sh "git remote add publish_git #{config.publish_git}"
|
34
|
-
sh
|
43
|
+
sh 'git add -A'
|
35
44
|
sh 'git commit -m "Add some more changes to API documentation" || true'
|
36
45
|
sh 'git push -f publish_git master'
|
37
46
|
end
|
38
47
|
end
|
39
48
|
end
|
40
49
|
|
41
|
-
desc
|
42
|
-
task :
|
50
|
+
desc 'Publish the newly created API documentation'
|
51
|
+
task publish: [:push]
|
43
52
|
|
44
|
-
desc
|
45
|
-
task :
|
53
|
+
desc 'Publish and view the newly created API documentation'
|
54
|
+
task view: :publish do
|
46
55
|
Betterdocs::Global.config do |config|
|
47
56
|
url = config.publish_git
|
48
|
-
if url !~ /\Ahttps?:/
|
49
|
-
url.sub!(/.*?([^@]*):/, 'http://\1/')
|
50
|
-
end
|
57
|
+
url.sub!(/.*?([^@]*):/, 'http://\1/') if url !~ /\Ahttps?:/
|
51
58
|
sh "open #{url.inspect}"
|
52
59
|
end
|
53
60
|
end
|
data/lib/betterdocs/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: betterdocs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- betterplace Developers
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gem_hadar
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.11.0
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.11.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
version: '3'
|
96
96
|
- - "<"
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version: '
|
98
|
+
version: '7'
|
99
99
|
type: :runtime
|
100
100
|
prerelease: false
|
101
101
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -105,7 +105,7 @@ dependencies:
|
|
105
105
|
version: '3'
|
106
106
|
- - "<"
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version: '
|
108
|
+
version: '7'
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
110
|
name: term-ansicolor
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,6 +190,7 @@ extra_rdoc_files:
|
|
190
190
|
- lib/betterdocs/dsl/result/property.rb
|
191
191
|
- lib/betterdocs/generator/config_shortcuts.rb
|
192
192
|
- lib/betterdocs/generator/markdown.rb
|
193
|
+
- lib/betterdocs/generator/swagger.rb
|
193
194
|
- lib/betterdocs/global.rb
|
194
195
|
- lib/betterdocs/json_params_representer.rb
|
195
196
|
- lib/betterdocs/json_params_representer_collector.rb
|
@@ -207,7 +208,9 @@ files:
|
|
207
208
|
- ".codeclimate.yml"
|
208
209
|
- ".gitignore"
|
209
210
|
- ".rspec"
|
210
|
-
- ".
|
211
|
+
- ".semaphore/semaphore.yml"
|
212
|
+
- ".tool-versions"
|
213
|
+
- ".vscode/settings.json"
|
211
214
|
- COPYING
|
212
215
|
- Gemfile
|
213
216
|
- LICENSE
|
@@ -238,6 +241,8 @@ files:
|
|
238
241
|
- lib/betterdocs/generator/markdown.rb
|
239
242
|
- lib/betterdocs/generator/markdown/templates/README.md.erb
|
240
243
|
- lib/betterdocs/generator/markdown/templates/section.md.erb
|
244
|
+
- lib/betterdocs/generator/swagger.rb
|
245
|
+
- lib/betterdocs/generator/swagger_static/index.html
|
241
246
|
- lib/betterdocs/global.rb
|
242
247
|
- lib/betterdocs/json_params_representer.rb
|
243
248
|
- lib/betterdocs/json_params_representer_collector.rb
|
@@ -273,7 +278,7 @@ files:
|
|
273
278
|
homepage: http://github.com/betterplace/betterdocs
|
274
279
|
licenses: []
|
275
280
|
metadata: {}
|
276
|
-
post_install_message:
|
281
|
+
post_install_message:
|
277
282
|
rdoc_options:
|
278
283
|
- "--title"
|
279
284
|
- Betterdocs
|
@@ -292,9 +297,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
292
297
|
- !ruby/object:Gem::Version
|
293
298
|
version: '0'
|
294
299
|
requirements: []
|
295
|
-
|
296
|
-
|
297
|
-
signing_key:
|
300
|
+
rubygems_version: 3.2.15
|
301
|
+
signing_key:
|
298
302
|
specification_version: 4
|
299
303
|
summary: Betterplace API documentation library
|
300
304
|
test_files:
|