apress-documentation 0.4.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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.drone.yml +28 -0
  3. data/.gitignore +10 -0
  4. data/Appraisals +30 -0
  5. data/CHANGELOG.md +34 -0
  6. data/Gemfile +4 -0
  7. data/README.md +101 -0
  8. data/Rakefile +6 -0
  9. data/app/assets/javascripts/package/documentation.js +18 -0
  10. data/app/assets/javascripts/shared/dependency_switcher.js +10 -0
  11. data/app/assets/javascripts/swagger_binder.js +19 -0
  12. data/app/assets/javascripts/swagger_ui.js +24 -0
  13. data/app/assets/javascripts/templates/document.hamlbars +25 -0
  14. data/app/assets/stylesheets/document/base.scss +112 -0
  15. data/app/assets/stylesheets/document/document.scss +19 -0
  16. data/app/assets/stylesheets/document/layout.scss +9 -0
  17. data/app/assets/stylesheets/document/sidebar.scss +19 -0
  18. data/app/assets/stylesheets/document/swagger.scss +3 -0
  19. data/app/assets/stylesheets/document/switch.scss +46 -0
  20. data/app/assets/stylesheets/document/variables.scss +26 -0
  21. data/app/assets/stylesheets/package/documentation.css +9 -0
  22. data/app/assets/stylesheets/package/swagger_print.css +4 -0
  23. data/app/assets/stylesheets/package/swagger_screen.css +4 -0
  24. data/app/controllers/apress/documentation/documents_controller.rb +14 -0
  25. data/app/controllers/apress/documentation/swagger_controller.rb +22 -0
  26. data/app/controllers/apress/documentation/swagger_ui_controller.rb +11 -0
  27. data/app/controllers/concerns/apress/documentation/preload_docs.rb +20 -0
  28. data/app/helpers/apress/documentation/documents_helper.rb +14 -0
  29. data/app/presenters/apress/documentation/dependency_presenter.rb +75 -0
  30. data/app/services/apress/documentation/swagger_json_builder.rb +22 -0
  31. data/app/views/apress/documentation/documents/_document.html.haml +32 -0
  32. data/app/views/apress/documentation/documents/_swagger.html.haml +10 -0
  33. data/app/views/apress/documentation/documents/show.html.haml +13 -0
  34. data/app/views/apress/documentation/presenters/dependency_presenter/_dependencies.html.haml +21 -0
  35. data/app/views/apress/documentation/presenters/dependency_presenter/_links.html.haml +17 -0
  36. data/app/views/apress/documentation/swagger_ui/show.html.haml +26 -0
  37. data/app/views/layouts/apress/documentation/_menu.html.haml +6 -0
  38. data/app/views/layouts/apress/documentation/_menu_item.html.haml +7 -0
  39. data/app/views/layouts/apress/documentation/_sidebar.html.haml +2 -0
  40. data/app/views/layouts/documentation.html.haml +17 -0
  41. data/apress-documentation.gemspec +35 -0
  42. data/config/routes.rb +16 -0
  43. data/dip.yml +48 -0
  44. data/docker-compose.development.yml +18 -0
  45. data/docker-compose.drone.yml +7 -0
  46. data/docker-compose.yml +10 -0
  47. data/lib/apress/documentation.rb +48 -0
  48. data/lib/apress/documentation/dsl/compilers/base_compiler.rb +32 -0
  49. data/lib/apress/documentation/dsl/compilers/document_compiler.rb +111 -0
  50. data/lib/apress/documentation/dsl/compilers/mixins/dependable.rb +31 -0
  51. data/lib/apress/documentation/dsl/compilers/mixins/publicity.rb +34 -0
  52. data/lib/apress/documentation/dsl/compilers/swagger_compiler.rb +25 -0
  53. data/lib/apress/documentation/dsl/document.rb +14 -0
  54. data/lib/apress/documentation/dsl/modules.rb +40 -0
  55. data/lib/apress/documentation/dsl/swagger_document.rb +14 -0
  56. data/lib/apress/documentation/dsl/utils/swagger_bind_point_extractor.rb +37 -0
  57. data/lib/apress/documentation/engine.rb +16 -0
  58. data/lib/apress/documentation/extensions/rgl/adjacency.rb +18 -0
  59. data/lib/apress/documentation/storage/base_storage.rb +88 -0
  60. data/lib/apress/documentation/storage/dependency_graph.rb +96 -0
  61. data/lib/apress/documentation/storage/document.rb +52 -0
  62. data/lib/apress/documentation/storage/modules.rb +83 -0
  63. data/lib/apress/documentation/storage/swagger_document.rb +62 -0
  64. data/lib/apress/documentation/swagger/schema.rb +39 -0
  65. data/lib/apress/documentation/version.rb +5 -0
  66. data/spec/app/controllers/documents_controller_spec.rb +42 -0
  67. data/spec/app/controllers/swagger_controller_spec.rb +46 -0
  68. data/spec/app/controllers/swagger_ui_controller_spec.rb +11 -0
  69. data/spec/app/services/swagger_json_builder_spec.rb +41 -0
  70. data/spec/apress/documentation_spec.rb +342 -0
  71. data/spec/helpers/apress/documentation/documents_helper_spec.rb +17 -0
  72. data/spec/internal/app/docs/swagger/root.rb +7 -0
  73. data/spec/internal/config/database.yml +7 -0
  74. data/spec/internal/config/environments/test.rb +1 -0
  75. data/spec/internal/config/hosts.rb +1 -0
  76. data/spec/internal/config/routes.rb +3 -0
  77. data/spec/internal/lib/stub_docs/module.rb +3 -0
  78. data/spec/internal/lib/stub_docs/module/document/child_document.rb +7 -0
  79. data/spec/internal/log/.gitignore +1 -0
  80. data/spec/presenters/apress/documentation/dependency_presenter_spec.rb +139 -0
  81. data/spec/spec_helper.rb +27 -0
  82. metadata +335 -0
@@ -0,0 +1,6 @@
1
+ %ul
2
+ %li
3
+ = link_to 'Главная', documentation_url
4
+ - menu.each do |_key, document|
5
+ %li
6
+ = render 'layouts/apress/documentation/menu_item', document: document
@@ -0,0 +1,7 @@
1
+ = link_to document.title || document.slug, documentation_url(path: document.slug)
2
+ - if document.documents.present?
3
+ %ul
4
+ - document.documents.each do |_key, document|
5
+ %li
6
+ = render 'layouts/apress/documentation/menu_item',
7
+ document: document
@@ -0,0 +1,2 @@
1
+ %aside.sidebar
2
+ = render 'layouts/apress/documentation/menu', menu: Apress::Documentation.data
@@ -0,0 +1,17 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ = stylesheet_link_tag 'package/swagger_screen', media: :screen
5
+ = stylesheet_link_tag 'package/swagger_print', media: :print
6
+ = stylesheet_link_tag 'package/documentation', media: 'all'
7
+ = javascript_include_tag 'package/documentation', defer: true
8
+ :javascript
9
+ var app = {};
10
+
11
+ %body
12
+ %main
13
+ - cache 'sidebar' do
14
+ = render 'layouts/apress/documentation/sidebar'
15
+
16
+ %section.content
17
+ = yield
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'apress/documentation/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'apress-documentation'
8
+ spec.version = Apress::Documentation::VERSION
9
+ spec.authors = ['Korobicyn Denis']
10
+ spec.email = ['deniskorobitcin@gmail.com']
11
+ spec.summary = 'apress-documentation'
12
+ spec.description = 'apress-documentation'
13
+ spec.homepage = 'https://github.com/abak-press/apress-documentation'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_runtime_dependency 'rails', '>= 3.2'
21
+ spec.add_runtime_dependency 'haml-rails', '>= 0.4'
22
+ spec.add_runtime_dependency 'swagger-blocks', '>= 1.3'
23
+ spec.add_runtime_dependency 'rgl'
24
+
25
+ spec.add_development_dependency "bundler", ">= 1.14"
26
+ spec.add_development_dependency "rake", ">= 10.0"
27
+ spec.add_development_dependency "rspec", ">= 3.0"
28
+ spec.add_development_dependency 'rspec-rails', '>= 3.2'
29
+ spec.add_development_dependency 'combustion', '>= 0.5.4'
30
+ spec.add_development_dependency 'appraisal'
31
+ spec.add_development_dependency 'simplecov', '>= 0.9'
32
+ spec.add_development_dependency "sqlite3"
33
+ spec.add_development_dependency 'test-unit'
34
+ spec.add_development_dependency 'pry-byebug'
35
+ end
@@ -0,0 +1,16 @@
1
+ Rails.application.routes.draw do
2
+ scope path: Apress::Documentation[:path_scope] do
3
+ scope module: :apress, constraints: Apress::Documentation[:routes_constraints] do
4
+ scope module: :documentation do
5
+ get "/documentation/(*path)", to: 'documents#show', as: :documentation
6
+ end
7
+
8
+ scope path: :api do
9
+ scope module: :documentation do
10
+ resource :swagger, controller: :swagger_ui, only: :show
11
+ resource :docs, controller: :swagger, only: :show
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
data/dip.yml ADDED
@@ -0,0 +1,48 @@
1
+ version: '1'
2
+
3
+ environment:
4
+ DOCKER_RUBY_VERSION: 2.2
5
+ RUBY_IMAGE_TAG: 2.2-latest
6
+ COMPOSE_FILE_EXT: development
7
+ RAILS_ENV: test
8
+ APRESS_GEMS_CREDENTIALS: ""
9
+
10
+ compose:
11
+ files:
12
+ - docker-compose.yml
13
+ - docker-compose.${COMPOSE_FILE_EXT}.yml
14
+
15
+ interaction:
16
+ sh:
17
+ service: app
18
+
19
+ irb:
20
+ service: app
21
+ command: bundle exec irb
22
+
23
+ bundle:
24
+ service: app
25
+ command: bundle
26
+
27
+ rake:
28
+ service: app
29
+ command: bundle exec rake
30
+
31
+ appraisal:
32
+ service: app
33
+ command: bundle exec appraisal
34
+
35
+ rspec:
36
+ service: app
37
+ command: bundle exec appraisal bundle exec rspec
38
+
39
+ clean:
40
+ service: app
41
+ command: rm -f Gemfile.lock gemfiles/*.gemfile.*
42
+
43
+ provision:
44
+ - docker volume create --name bundler_data
45
+ - dip bundle config --local https://gems.railsc.ru/ ${APRESS_GEMS_CREDENTIALS}
46
+ - dip clean
47
+ - dip bundle install
48
+ - dip appraisal install
@@ -0,0 +1,18 @@
1
+ version: '2'
2
+
3
+ services:
4
+ app:
5
+ volumes:
6
+ - .:/app
7
+ - ../:/localgems
8
+ - ssh-data:/ssh:ro
9
+ - bundler-data:/bundle
10
+
11
+ volumes:
12
+ bundler-data:
13
+ external:
14
+ name: bundler_data
15
+
16
+ ssh-data:
17
+ external:
18
+ name: ssh_data
@@ -0,0 +1,7 @@
1
+ version: '2'
2
+
3
+ services:
4
+ app:
5
+ volumes:
6
+ - .:/app
7
+ - /bundle:/bundle
@@ -0,0 +1,10 @@
1
+ version: '2'
2
+
3
+ services:
4
+ app:
5
+ image: abakpress/ruby-app:$RUBY_IMAGE_TAG
6
+ environment:
7
+ - BUNDLE_PATH=/bundle/$DOCKER_RUBY_VERSION
8
+ - BUNDLE_CONFIG=/app/.bundle/config
9
+ - SSH_AUTH_SOCK=/ssh/auth/sock
10
+ command: bash
@@ -0,0 +1,48 @@
1
+ require 'rails/all'
2
+ require 'haml-rails'
3
+ require 'swagger/blocks'
4
+ require 'rgl/adjacency'
5
+ require 'rgl/dot'
6
+ require 'apress/documentation/extensions/rgl/adjacency'
7
+ require 'apress/documentation/swagger/schema'
8
+ require 'apress/documentation/storage/dependency_graph'
9
+ require 'apress/documentation/storage/swagger_document'
10
+ require 'apress/documentation/storage/document'
11
+ require 'apress/documentation/storage/modules'
12
+ require 'apress/documentation/engine'
13
+ require "apress/documentation/version"
14
+
15
+ # Public: Основной модуль для использования
16
+ #
17
+ # Содержит методы построения и получения динамически определяемых документов
18
+ module Apress
19
+ module Documentation
20
+ def self.modules
21
+ Apress::Documentation::Storage::Modules.instance
22
+ end
23
+
24
+ def self.add_load_path(path)
25
+ ActiveSupport.on_load(:documentation) do
26
+ Dir[File.join(path, '/**/*.rb')].each { |file| require file }
27
+
28
+ yield if block_given?
29
+ end
30
+ end
31
+
32
+ def self.reset!
33
+ Apress::Documentation::Storage::DependencyGraph.instance.reset!
34
+ modules.reset!
35
+ end
36
+
37
+ def self.validate_dependencies!
38
+ Apress::Documentation::Storage::DependencyGraph.instance.validate!
39
+ end
40
+
41
+ class << self
42
+ extend Forwardable
43
+
44
+ def_delegators :modules, :data, :fetch_document, :build
45
+ def_delegators 'Rails.application.config.documentation', :[], :[]=, :fetch
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,32 @@
1
+ module Apress
2
+ module Documentation
3
+ module Dsl
4
+ # Private: AbstractClass Базовы класс компилятора DSL
5
+ #
6
+ # задает DSL для настройки DSL (Xzibit style)
7
+ class BaseCompiler
8
+ # Public: Объект в который будут заполняться поля чере DSL
9
+ attr_reader :target
10
+
11
+ def initialize(target)
12
+ @target = target
13
+ end
14
+
15
+ # Public: Основной метод, задает какие поля объект DSL-класса будет записивать в target
16
+ def self.setters(*method_names)
17
+ method_names.each do |name|
18
+ send :define_method, name do |value|
19
+ @target.send("#{name}=", value)
20
+ end
21
+ end
22
+ end
23
+
24
+ # Public: Осуществляет исполнение DSL и заполняет нужные поля в target
25
+ def compile(fields, &block)
26
+ @target.assign(fields)
27
+ instance_eval(&block) if block_given?
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,111 @@
1
+ require_relative 'base_compiler'
2
+ require_relative '../utils/swagger_bind_point_extractor'
3
+ require_relative './mixins/dependable'
4
+ require_relative './mixins/publicity'
5
+
6
+ module Apress
7
+ module Documentation
8
+ module Dsl
9
+ module Compilers
10
+ # Private: "Компилирует" блок для объекта класса Document заполняя в нем нужные аттрибуты
11
+ class DocumentCompiler < BaseCompiler
12
+ include Apress::Documentation::Dsl::Mixins::Dependable
13
+ include Apress::Documentation::Dsl::Mixins::Publicity
14
+ setters :title,
15
+ :description,
16
+ :business_desc,
17
+ :tests
18
+
19
+ # Public: метод DSL, Создает документ, осуществляет вложеность документов
20
+ #
21
+ # slug - (required), String or Symbol - слаг документа
22
+ # fields - Hash - позволяет задавать поля через хеш
23
+ # block - Proc - DSL для настройки полей документа
24
+ #
25
+ # Examples
26
+ #
27
+ # Apress::Documentation.build(:module) do
28
+ # document(:html) do
29
+ # description 'Описывает все HTMl старницы'
30
+ # document(:page) do
31
+ # description 'Тут описание только одной'
32
+ # end
33
+ # end
34
+ # end
35
+ #
36
+ # Можно вызывать без блока
37
+ # Apress::Documentation.build(:module) do
38
+ # document :name, title: :test, description: 'some description'
39
+ # end
40
+ def document(slug, fields = {}, &block)
41
+ slug = slug.to_s
42
+ doc = target.documents[slug]
43
+ doc ||= Apress::Documentation::Storage::Document.new(target.slug + '/' + slug)
44
+ Storage::DependencyGraph.instance.add_document(doc)
45
+
46
+ target.documents[slug] = doc
47
+ doc.compile(fields, &block)
48
+ end
49
+
50
+ # Public: метод DSL, Создает swagger-описание внутри документа.
51
+ #
52
+ # slug - (required), String or Symbol - слаг документа
53
+ # fields - Hash - позволяет задавать поля через хеш
54
+ # block - Proc - DSL для настройки полей документа
55
+ #
56
+ # Examples
57
+ #
58
+ # Apress::Documentation.build(:module) do
59
+ # document(:http_api) do
60
+ # description 'Описывает все API модуля'
61
+ # swagger_bind('tag_operationId_content') do
62
+ # description 'Тут описание только одной'
63
+ # swagger_path('api/docs') do
64
+ # # Тут вызовы методов Swagger::Blocks
65
+ # end
66
+ # end
67
+ # end
68
+ # end
69
+ #
70
+ # Можно вызывать без указания html_id,
71
+ # тогда он будет "распознан" из блока автоматически, если это возможно.
72
+ # В случае если html_id не был передан и "распознать" html_id невозможно, будет кинуто исключение.
73
+ #
74
+ # Детали "распознования" см. в Apress::Documentation::Dsl::Utils::SwaggerBindPointExtractor
75
+ #
76
+ # Apress::Documentation.build(:module) do
77
+ # document(:http_api) do
78
+ # description 'Описывает все API модуля'
79
+ # swagger_bind do # -> будет tag_operationId_content
80
+ # description 'Тут описание только одной'
81
+ # swagger_path('api/docs') do
82
+ # operation :get do
83
+ # key :operationId, 'operationId' # -> обязательный вызов для распознавания
84
+ # key :tags, ['tag'] # -> обязательный вызов для распознавания
85
+ # end
86
+ # end
87
+ # end
88
+ # end
89
+ # end
90
+ def swagger_bind(html_id = nil, fields = {}, &block)
91
+ html_id = recognize_html_id(html_id, &block)
92
+ doc = target.swagger_documents[html_id]
93
+ doc ||= Apress::Documentation::Storage::SwaggerDocument.new(target, html_id)
94
+ Storage::DependencyGraph.instance.add_document(doc)
95
+
96
+ target.swagger_documents[html_id] = doc
97
+ doc.compile(fields, &block)
98
+ end
99
+
100
+ private
101
+
102
+ def recognize_html_id(html_id, &block)
103
+ html_id ||= Apress::Documentation::Dsl::Utils::SwaggerBindPointExtractor.new.extract(&block)
104
+ raise "Could not recognize html_id from block" unless html_id
105
+ html_id.to_s
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,31 @@
1
+ module Apress
2
+ module Documentation
3
+ module Dsl
4
+ module Mixins
5
+ module Dependable
6
+ # Public: создает зависимости между документами, является частью DSL
7
+ #
8
+ # Arguments:
9
+ # documents_slugs - Массив полных слагов для документом от которых зависит текущий документ.
10
+ # Examples:
11
+ # Apress::Documentation.build(:module) do
12
+ # document(:doc2) do
13
+ # depends_on('module/doc1', 'other_model/other_document')
14
+ # end
15
+ #
16
+ # document(:doc1)
17
+ # end
18
+ #
19
+ def depends_on(*documents_slugs)
20
+ documents_slugs.each do |document_slug|
21
+ document = Apress::Documentation::Storage::Modules.instance.fetch_document(document_slug)
22
+ document ||= document_slug
23
+ Apress::Documentation::Storage::DependencyGraph.instance.add_document(document)
24
+ Apress::Documentation::Storage::DependencyGraph.instance.add_dependency(@target, document)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ module Apress
2
+ module Documentation
3
+ module Dsl
4
+ module Mixins
5
+ module Publicity
6
+ ACCESS_MAPPING = {
7
+ public: 'Публичный',
8
+ private: 'Приватный',
9
+ protected: 'Защищеный'
10
+ }.freeze
11
+
12
+ # Public: указывает уровень доступа документа, является частью DSL
13
+ #
14
+ # Arguments:
15
+ # level - Symbol, valid values - :public, :private, :protected
16
+ # Examples:
17
+ # Apress::Documentation.build(:module) do
18
+ # document(:doc1) do
19
+ # publicity :public
20
+ # end
21
+ # end
22
+ #
23
+ def publicity(level)
24
+ unless ACCESS_MAPPING.keys.include?(level)
25
+ raise "Неизвестный уровень доступа - #{level}, объявлен в документе #{@target.slug}"
26
+ end
27
+
28
+ @target.publicity = ACCESS_MAPPING[level]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,25 @@
1
+ require_relative 'base_compiler'
2
+ require_relative './mixins/dependable'
3
+ require_relative './mixins/publicity'
4
+
5
+ module Apress
6
+ module Documentation
7
+ module Dsl
8
+ module Compilers
9
+ # Private: "Компилирует" блок для объекта класса SwaggerDocument заполняя в нем нужные аттрибуты
10
+ class SwaggerCompiler < BaseCompiler
11
+ include Apress::Documentation::Dsl::Mixins::Dependable
12
+ include Apress::Documentation::Dsl::Mixins::Publicity
13
+ extend Forwardable
14
+
15
+ alias_method :swagger_document, :target
16
+ setters :business_desc,
17
+ :tests
18
+
19
+ def_delegators :swagger_document, :swagger_class
20
+ def_delegators :swagger_class, :swagger_path
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end