apress-documentation 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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