cabbage_doc 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cabbage_doc.rb +7 -2
- data/lib/cabbage_doc/action.rb +1 -1
- data/lib/cabbage_doc/authentication.rb +13 -4
- data/lib/cabbage_doc/client.rb +2 -0
- data/lib/cabbage_doc/collection.rb +23 -6
- data/lib/cabbage_doc/configuration.rb +14 -4
- data/lib/cabbage_doc/controller.rb +15 -9
- data/lib/cabbage_doc/example.rb +1 -1
- data/lib/cabbage_doc/{processor.rb → generator.rb} +41 -21
- data/lib/cabbage_doc/generators/api.rb +39 -0
- data/lib/cabbage_doc/generators/pages.rb +33 -0
- data/lib/cabbage_doc/parameter.rb +1 -1
- data/lib/cabbage_doc/params.rb +6 -2
- data/lib/cabbage_doc/parser.rb +3 -3
- data/lib/cabbage_doc/request.rb +24 -7
- data/lib/cabbage_doc/response.rb +1 -1
- data/lib/cabbage_doc/task.rb +55 -23
- data/lib/cabbage_doc/version.rb +1 -1
- data/lib/cabbage_doc/web.rb +17 -3
- data/lib/cabbage_doc/web_helper.rb +13 -3
- data/web/public/css/application.css +1 -25
- data/web/public/css/base.css +23 -0
- data/web/public/js/application.js +6 -5
- data/web/views/action.haml +3 -3
- data/web/views/api.haml +14 -0
- data/web/views/controller.haml +1 -1
- data/web/views/controllers.haml +3 -0
- data/web/views/index.haml +5 -2
- data/web/views/layout.haml +1 -0
- data/web/views/page.haml +1 -0
- data/web/views/page_layout.haml +13 -0
- metadata +24 -5
- data/lib/cabbage_doc/processors/documentation.rb +0 -17
- data/web/views/documentation.haml +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7bdad905798e6ed0c5e62b8ec075359acf0eb78c
|
4
|
+
data.tar.gz: 40c4b70fdaebe890f108ecd2cfc94c8e82608782
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 493affb4f721afd804dfb7fcfb251d8bf22d36a8754452f727e0cc98816f5bc9aca235f308623435aac67a74ff45bffab1586188627d470e95c220a31614894a
|
7
|
+
data.tar.gz: 3410ed1938d0e208c1a61a1fb4918725fe922125269a36dbdfd2892a7cc44a89cbfe748d91bdeab4cf70f48f007ba3352866ced565f776529d3b98ea418f6119
|
data/lib/cabbage_doc.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module CabbageDoc
|
2
|
+
TAG = :api
|
2
3
|
MARKER = ':cabbagedoc:'.freeze
|
3
|
-
VISIBILITY = %i(public private internal beta).freeze
|
4
|
+
VISIBILITY = %i(public private internal beta unreleased).freeze
|
4
5
|
VISIBILITY_REGEXP = VISIBILITY.map(&:to_s).map(&:capitalize).join('|').freeze
|
5
6
|
|
6
7
|
autoload :Path, 'cabbage_doc/path'
|
@@ -20,7 +21,7 @@ module CabbageDoc
|
|
20
21
|
autoload :Collection, 'cabbage_doc/collection'
|
21
22
|
autoload :WebHelper, 'cabbage_doc/web_helper'
|
22
23
|
autoload :Web, 'cabbage_doc/web'
|
23
|
-
autoload :
|
24
|
+
autoload :Generator, 'cabbage_doc/generator'
|
24
25
|
autoload :Customizer, 'cabbage_doc/customizer'
|
25
26
|
autoload :Task, 'cabbage_doc/task'
|
26
27
|
autoload :Worker, 'cabbage_doc/worker'
|
@@ -33,5 +34,9 @@ module CabbageDoc
|
|
33
34
|
config.validate!
|
34
35
|
end
|
35
36
|
end
|
37
|
+
|
38
|
+
def glob(*args)
|
39
|
+
proc { Dir.glob(File.join(*args)).sort.reverse }
|
40
|
+
end
|
36
41
|
end
|
37
42
|
end
|
data/lib/cabbage_doc/action.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
module CabbageDoc
|
2
2
|
class Authentication
|
3
3
|
class << self
|
4
|
-
def new(request = nil)
|
4
|
+
def new(request = nil, tag = nil)
|
5
5
|
super().tap do |auth|
|
6
|
+
auth.tag = tag if tag
|
6
7
|
yield(auth) if block_given?
|
7
8
|
Configuration.instance.authentication.call(auth, request)
|
8
9
|
end
|
@@ -21,7 +22,9 @@ module CabbageDoc
|
|
21
22
|
:user_agent,
|
22
23
|
:configurable,
|
23
24
|
:verbose,
|
24
|
-
:visibility
|
25
|
+
:visibility,
|
26
|
+
:tag,
|
27
|
+
:json
|
25
28
|
|
26
29
|
def initialize
|
27
30
|
Configuration.instance.tap do |config|
|
@@ -31,6 +34,8 @@ module CabbageDoc
|
|
31
34
|
@user_agent = config.title
|
32
35
|
@verbose = config.verbose
|
33
36
|
@visibility = config.visibility.dup
|
37
|
+
@tag = config.tags.first
|
38
|
+
@json = config.json
|
34
39
|
end
|
35
40
|
|
36
41
|
@subdomains = []
|
@@ -53,9 +58,9 @@ module CabbageDoc
|
|
53
58
|
def valid?
|
54
59
|
case type
|
55
60
|
when :basic
|
56
|
-
username && password
|
61
|
+
username && password && valid_subdomain?
|
57
62
|
else
|
58
|
-
!token.nil?
|
63
|
+
!token.nil? && valid_subdomain?
|
59
64
|
end
|
60
65
|
end
|
61
66
|
|
@@ -65,6 +70,10 @@ module CabbageDoc
|
|
65
70
|
|
66
71
|
private
|
67
72
|
|
73
|
+
def valid_subdomain?
|
74
|
+
!configurable.include?(:subdomain) || subdomain
|
75
|
+
end
|
76
|
+
|
68
77
|
def root_uri
|
69
78
|
if subdomain
|
70
79
|
"#{scheme}://#{subdomain}.#{domain}"
|
data/lib/cabbage_doc/client.rb
CHANGED
@@ -32,22 +32,26 @@ module CabbageDoc
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def parse!(filename)
|
35
|
+
def parse!(filename, tag = TAG)
|
36
36
|
text = File.read(filename) rescue nil
|
37
37
|
return false unless text
|
38
38
|
|
39
|
-
controller = Controller.parse(text)
|
39
|
+
controller = Controller.parse(text, tag)
|
40
40
|
return false unless controller
|
41
41
|
|
42
|
-
controllers = controller.eval(text)
|
42
|
+
controllers = controller.eval(text, tag)
|
43
43
|
|
44
44
|
@_controllers.concat(controllers)
|
45
45
|
|
46
46
|
controllers.any?
|
47
47
|
end
|
48
48
|
|
49
|
-
def clear!
|
50
|
-
|
49
|
+
def clear!(tag = nil)
|
50
|
+
if tag && config.tags.size > 1
|
51
|
+
@_controllers.reject! { |controller| tag == controller.tag }
|
52
|
+
else
|
53
|
+
@_controllers = []
|
54
|
+
end
|
51
55
|
end
|
52
56
|
|
53
57
|
def load!
|
@@ -55,13 +59,26 @@ module CabbageDoc
|
|
55
59
|
end
|
56
60
|
|
57
61
|
def save!
|
62
|
+
sort!
|
58
63
|
open(filename, 'w') { |f| f.write(YAML.dump(@_controllers)) } rescue nil
|
59
64
|
end
|
60
65
|
|
61
66
|
private
|
62
67
|
|
68
|
+
def sort!
|
69
|
+
return unless config.tags.size > 1
|
70
|
+
|
71
|
+
@_controllers.sort! do |controller|
|
72
|
+
-config.tags.index(controller.tag)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def config
|
77
|
+
@_config ||= Configuration.instance
|
78
|
+
end
|
79
|
+
|
63
80
|
def filename
|
64
|
-
@_filename ||= Path.join(
|
81
|
+
@_filename ||= Path.join(config.root, FILENAME)
|
65
82
|
end
|
66
83
|
end
|
67
84
|
end
|
@@ -30,7 +30,8 @@ module CabbageDoc
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
DEFAULTS =
|
33
|
+
DEFAULTS =
|
34
|
+
{
|
34
35
|
path: 'api/v1',
|
35
36
|
title: 'Cabbage Doc',
|
36
37
|
scheme: 'https',
|
@@ -41,10 +42,18 @@ module CabbageDoc
|
|
41
42
|
request: proc { |request| request.perform },
|
42
43
|
theme: 'github',
|
43
44
|
examples: false,
|
44
|
-
format_example: method(:format_example)
|
45
|
+
format_example: method(:format_example),
|
46
|
+
page_root: 'pages',
|
47
|
+
page_ext: 'md',
|
48
|
+
auto_generate: true,
|
49
|
+
generators: [:api],
|
50
|
+
tags: [TAG],
|
51
|
+
json: false
|
45
52
|
}.freeze
|
46
53
|
|
47
|
-
OPTIONAL_ATTRIBUTES = %i(welcome path scheme title verbose authentication dev request cache
|
54
|
+
OPTIONAL_ATTRIBUTES = %i(welcome path scheme title verbose authentication dev request cache
|
55
|
+
theme visibility examples format_example page_root page_ext
|
56
|
+
asset_path auto_generate generators tags json).freeze
|
48
57
|
REQUIRED_ATTRIBUTES = %i(domain controllers root).freeze
|
49
58
|
ATTRIBUTES = (OPTIONAL_ATTRIBUTES + REQUIRED_ATTRIBUTES).freeze
|
50
59
|
CALLABLE_ATTRIBUTES = %i(controllers authentication request format_example).freeze
|
@@ -87,7 +96,8 @@ module CabbageDoc
|
|
87
96
|
def validate_visibility!
|
88
97
|
self.visibility = Array(visibility)
|
89
98
|
self.visibility.each do |v|
|
90
|
-
|
99
|
+
valid = VISIBILITY.include?(v) || tags.include?(v)
|
100
|
+
raise ArgumentError, "#{v} invalid visibility" unless valid
|
91
101
|
end
|
92
102
|
end
|
93
103
|
end
|
@@ -3,15 +3,16 @@ module CabbageDoc
|
|
3
3
|
include Parser
|
4
4
|
include Cloneable
|
5
5
|
|
6
|
-
attr_reader :label, :klass, :name, :path, :actions, :visibility
|
6
|
+
attr_reader :label, :klass, :name, :path, :actions, :visibility, :tag
|
7
7
|
|
8
|
-
def initialize
|
8
|
+
def initialize(tag = TAG)
|
9
9
|
@actions = []
|
10
10
|
@visibility = VISIBILITY.first
|
11
|
+
@tag = tag
|
11
12
|
end
|
12
13
|
|
13
|
-
def parse(text)
|
14
|
-
@label, @path, @klass, @visibility =
|
14
|
+
def parse(text, tag = TAG)
|
15
|
+
@label, @path, @klass, @visibility, @tag = parse_label_path_class_visibility_and_tag(text, tag)
|
15
16
|
return false unless @label && @klass
|
16
17
|
|
17
18
|
@name = compose_name(klass)
|
@@ -31,7 +32,7 @@ module CabbageDoc
|
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
|
-
def eval(text)
|
35
|
+
def eval(text, tag)
|
35
36
|
return [self] unless template?
|
36
37
|
|
37
38
|
templates = []
|
@@ -50,7 +51,7 @@ module CabbageDoc
|
|
50
51
|
template_text.gsub!(template[:text], template[:values].shift.to_s)
|
51
52
|
end
|
52
53
|
|
53
|
-
self.class.parse(template_text)
|
54
|
+
self.class.parse(template_text, tag)
|
54
55
|
end.compact
|
55
56
|
end
|
56
57
|
|
@@ -69,10 +70,14 @@ module CabbageDoc
|
|
69
70
|
end
|
70
71
|
|
71
72
|
def compose_visbility(metadata)
|
72
|
-
metadata[:visibility] ||
|
73
|
+
metadata[:visibility] || VISIBILITY.first
|
73
74
|
end
|
74
75
|
|
75
|
-
def
|
76
|
+
def compose_tag(metadata, tag = TAG)
|
77
|
+
metadata[:tag]&.to_sym || tag
|
78
|
+
end
|
79
|
+
|
80
|
+
def parse_label_path_class_visibility_and_tag(text, tag = TAG)
|
76
81
|
klass = parse_class(text)
|
77
82
|
return unless klass
|
78
83
|
|
@@ -82,7 +87,8 @@ module CabbageDoc
|
|
82
87
|
compose_label(metadata, klass),
|
83
88
|
compose_path(metadata, klass),
|
84
89
|
klass,
|
85
|
-
compose_visbility(metadata)
|
90
|
+
compose_visbility(metadata),
|
91
|
+
compose_tag(metadata, tag)
|
86
92
|
]
|
87
93
|
end
|
88
94
|
|
data/lib/cabbage_doc/example.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module CabbageDoc
|
2
|
-
class
|
2
|
+
class Generator
|
3
3
|
class Error < StandardError; end
|
4
4
|
class InvalidType < Error; end
|
5
5
|
class InvalidPriority < Error; end
|
@@ -11,6 +11,14 @@ module CabbageDoc
|
|
11
11
|
all[klass.to_s.split('::').last.downcase.to_sym] = klass
|
12
12
|
end
|
13
13
|
|
14
|
+
def tags(value = nil)
|
15
|
+
if value.nil?
|
16
|
+
@_tags
|
17
|
+
else
|
18
|
+
@_tags = !!value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
14
22
|
def priority(value = nil)
|
15
23
|
if value.is_a?(Symbol)
|
16
24
|
raise InvalidPriority, value unless PRIORITIES.include?(value)
|
@@ -24,40 +32,48 @@ module CabbageDoc
|
|
24
32
|
@_all ||= {}
|
25
33
|
end
|
26
34
|
|
27
|
-
def
|
28
|
-
|
35
|
+
def supports?(type, what)
|
36
|
+
!!find(type).public_send(what)
|
37
|
+
end
|
29
38
|
|
30
|
-
|
31
|
-
|
39
|
+
def exists?(type)
|
40
|
+
all.has_key?(type)
|
41
|
+
end
|
42
|
+
|
43
|
+
def perform(type, tag = nil)
|
44
|
+
if type == :all
|
45
|
+
all.map { |_, klass| klass.new(tag).perform }
|
32
46
|
else
|
33
|
-
|
47
|
+
find(type).new(tag).perform
|
34
48
|
end
|
35
49
|
end
|
36
50
|
|
51
|
+
def find(type)
|
52
|
+
klass = all[type]
|
53
|
+
|
54
|
+
raise InvalidType, type unless klass
|
55
|
+
|
56
|
+
klass
|
57
|
+
end
|
58
|
+
|
37
59
|
def load!
|
38
|
-
Dir.glob(File.join(File.dirname(__FILE__), '
|
39
|
-
require(
|
60
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'generators', '*.rb')).sort.each do |generator|
|
61
|
+
require(generator)
|
40
62
|
end
|
41
63
|
end
|
42
64
|
end
|
43
65
|
|
44
|
-
|
45
|
-
raise NotImplementedError
|
46
|
-
end
|
47
|
-
|
48
|
-
protected
|
66
|
+
attr_accessor :tag
|
49
67
|
|
50
|
-
def
|
51
|
-
|
68
|
+
def initialize(tag = nil)
|
69
|
+
self.tag = tag
|
52
70
|
end
|
53
71
|
|
54
|
-
def
|
55
|
-
|
72
|
+
def perform
|
73
|
+
raise NotImplementedError
|
56
74
|
end
|
57
75
|
|
58
|
-
|
59
|
-
@_auth ||= Authentication.new
|
60
|
-
end
|
76
|
+
protected
|
61
77
|
|
62
78
|
def collection
|
63
79
|
@_collection ||= Collection.instance.tap do |collection|
|
@@ -65,10 +81,14 @@ module CabbageDoc
|
|
65
81
|
end
|
66
82
|
end
|
67
83
|
|
84
|
+
def controllers
|
85
|
+
@_controllers ||= config.controllers.call
|
86
|
+
end
|
87
|
+
|
68
88
|
def config
|
69
89
|
@_config ||= Configuration.instance
|
70
90
|
end
|
71
91
|
end
|
72
92
|
|
73
|
-
|
93
|
+
Generator.load!
|
74
94
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module CabbageDoc
|
2
|
+
module Generators
|
3
|
+
class Api < Generator
|
4
|
+
priority :high
|
5
|
+
tags true
|
6
|
+
|
7
|
+
def perform
|
8
|
+
collection.clear!(tag)
|
9
|
+
|
10
|
+
if controllers.is_a?(Hash)
|
11
|
+
parse_with_tag!
|
12
|
+
else
|
13
|
+
parse_without_tag!
|
14
|
+
end
|
15
|
+
|
16
|
+
collection.save!
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def parse_with_tag!
|
22
|
+
controllers.each do |tag, filenames|
|
23
|
+
next if self.tag && self.tag != tag
|
24
|
+
next unless filenames.respond_to?(:call)
|
25
|
+
|
26
|
+
filenames.call.each do |filename|
|
27
|
+
collection.parse!(filename, tag)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_without_tag!
|
33
|
+
controllers.each do |filename|
|
34
|
+
collection.parse!(filename)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module CabbageDoc
|
2
|
+
module Generators
|
3
|
+
class Pages < Generator
|
4
|
+
priority :low
|
5
|
+
|
6
|
+
def perform
|
7
|
+
pages.each do |file|
|
8
|
+
generate(file)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def generate(file)
|
15
|
+
open(file.sub(/#{config.page_ext}$/, 'html'), 'w') do |f|
|
16
|
+
f.write(helper.markdown.render(File.read(file)))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def pages
|
21
|
+
@_pages ||= Dir.glob(File.join(config.root, config.page_root, "*.#{config.page_ext}"))
|
22
|
+
end
|
23
|
+
|
24
|
+
class Helper
|
25
|
+
include CabbageDoc::WebHelper
|
26
|
+
end
|
27
|
+
|
28
|
+
def helper
|
29
|
+
@_helper ||= Helper.new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/cabbage_doc/params.rb
CHANGED
@@ -2,6 +2,10 @@ module CabbageDoc
|
|
2
2
|
class Params
|
3
3
|
include Enumerable
|
4
4
|
|
5
|
+
ACTION = '__action'.freeze
|
6
|
+
METHOD = '__method'.freeze
|
7
|
+
TAG = '__tag'.freeze
|
8
|
+
|
5
9
|
def initialize(params, collection)
|
6
10
|
@_params = convert(params, collection)
|
7
11
|
end
|
@@ -41,8 +45,8 @@ module CabbageDoc
|
|
41
45
|
private
|
42
46
|
|
43
47
|
def convert(params, collection)
|
44
|
-
method = params[
|
45
|
-
action = params[
|
48
|
+
method = params[METHOD]
|
49
|
+
action = params[ACTION]
|
46
50
|
|
47
51
|
return {} unless action && method
|
48
52
|
|
data/lib/cabbage_doc/parser.rb
CHANGED
@@ -7,13 +7,13 @@ module CabbageDoc
|
|
7
7
|
end
|
8
8
|
|
9
9
|
module ClassMethods
|
10
|
-
def parse(text)
|
10
|
+
def parse(text, tag = TAG)
|
11
11
|
instance = new
|
12
|
-
instance if instance.parse(text)
|
12
|
+
instance if instance.parse(text, tag)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def parse(text)
|
16
|
+
def parse(text, tag = TAG)
|
17
17
|
raise NotImplementedError
|
18
18
|
end
|
19
19
|
|
data/lib/cabbage_doc/request.rb
CHANGED
@@ -9,11 +9,11 @@ module CabbageDoc
|
|
9
9
|
attr_reader :raw_request, :collection
|
10
10
|
|
11
11
|
class << self
|
12
|
-
def parse(s)
|
12
|
+
def parse(s, tag = TAG)
|
13
13
|
variables = YAML.load(s)
|
14
14
|
|
15
15
|
new(OpenStruct.new(params: {}, env: {}), Collection.instance).tap do |instance|
|
16
|
-
[:@_id, :@_auth, :@_action, :@_method, :@_params].each_with_index do |k, i|
|
16
|
+
[:@_id, :@_auth, :@_action, :@_method, :@_tag, :@_params].each_with_index do |k, i|
|
17
17
|
instance.instance_variable_set(k, variables[i])
|
18
18
|
end
|
19
19
|
end
|
@@ -30,7 +30,7 @@ module CabbageDoc
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def valid?
|
33
|
-
action && method && METHODS.include?(method)
|
33
|
+
action && method && METHODS.include?(method) && auth.valid?
|
34
34
|
end
|
35
35
|
|
36
36
|
def to_yaml
|
@@ -39,6 +39,7 @@ module CabbageDoc
|
|
39
39
|
auth,
|
40
40
|
action,
|
41
41
|
method,
|
42
|
+
tag,
|
42
43
|
params
|
43
44
|
])
|
44
45
|
end
|
@@ -56,7 +57,11 @@ module CabbageDoc
|
|
56
57
|
|
57
58
|
def perform_request
|
58
59
|
key = (method == :get) ? :query : :body
|
59
|
-
|
60
|
+
|
61
|
+
data = params.to_hash
|
62
|
+
data = data.to_json if key == :body && auth.json
|
63
|
+
|
64
|
+
client.public_send(method, action, key => data)
|
60
65
|
end
|
61
66
|
|
62
67
|
def url
|
@@ -64,11 +69,15 @@ module CabbageDoc
|
|
64
69
|
end
|
65
70
|
|
66
71
|
def action
|
67
|
-
@_action ||= compose_action(raw_request.params[
|
72
|
+
@_action ||= compose_action(raw_request.params[Params::ACTION])
|
68
73
|
end
|
69
74
|
|
70
75
|
def method
|
71
|
-
@_method ||= compose_method(raw_request.params[
|
76
|
+
@_method ||= compose_method(raw_request.params[Params::METHOD])
|
77
|
+
end
|
78
|
+
|
79
|
+
def tag
|
80
|
+
@_tag ||= compose_tag(raw_request.params[Params::TAG])
|
72
81
|
end
|
73
82
|
|
74
83
|
def compose_method(method)
|
@@ -90,12 +99,20 @@ module CabbageDoc
|
|
90
99
|
action
|
91
100
|
end
|
92
101
|
|
102
|
+
def compose_tag(tag)
|
103
|
+
if tag
|
104
|
+
tag.downcase.to_sym
|
105
|
+
else
|
106
|
+
TAG
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
93
110
|
def params
|
94
111
|
@_params ||= Params.new(raw_params, collection)
|
95
112
|
end
|
96
113
|
|
97
114
|
def auth
|
98
|
-
@_auth ||= Authentication.new(raw_request)
|
115
|
+
@_auth ||= Authentication.new(raw_request, tag)
|
99
116
|
end
|
100
117
|
|
101
118
|
def raw_params
|
data/lib/cabbage_doc/response.rb
CHANGED
data/lib/cabbage_doc/task.rb
CHANGED
@@ -3,7 +3,7 @@ require 'rake/tasklib'
|
|
3
3
|
|
4
4
|
module CabbageDoc
|
5
5
|
class Task < Rake::TaskLib
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :generators, :tags, :name, :customize
|
7
7
|
|
8
8
|
def self.define
|
9
9
|
new.tap do |instance|
|
@@ -15,45 +15,77 @@ module CabbageDoc
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def initialize
|
18
|
-
|
19
|
-
|
18
|
+
self.generators = config.generators.dup
|
19
|
+
self.tags = config.tags.dup
|
20
|
+
self.name = :cabbagedoc
|
21
|
+
self.customize = true
|
22
|
+
end
|
23
|
+
|
24
|
+
def config
|
25
|
+
@_config ||= Configuration.instance
|
20
26
|
end
|
21
27
|
|
22
28
|
def sort!
|
23
|
-
|
29
|
+
generators.sort! { |generator| Generator::PRIORITIES.index(Generator.all[generator].priority) }
|
24
30
|
end
|
25
31
|
|
26
32
|
def define!
|
27
33
|
namespace name do
|
28
|
-
|
29
|
-
|
30
|
-
namespace :process do
|
31
|
-
task processor.to_s => :environment do
|
32
|
-
Processor.all[processor].new.perform
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
desc "Customize Web UI"
|
38
|
-
task :customize => :environment do
|
39
|
-
Customizer.new.perform
|
40
|
-
end
|
34
|
+
define_generators!
|
35
|
+
define_customizer!
|
41
36
|
end
|
42
37
|
|
43
|
-
desc "Run all
|
38
|
+
desc "Run all generators"
|
44
39
|
task name => :environment do
|
45
|
-
|
46
|
-
|
40
|
+
generators.each do |type|
|
41
|
+
Generator.perform(type)
|
47
42
|
end
|
48
43
|
end
|
49
44
|
end
|
50
45
|
|
51
46
|
def validate!
|
52
47
|
fail "Invalid 'name'" unless name.is_a?(Symbol)
|
53
|
-
fail "No '
|
48
|
+
fail "No 'generators' configured" unless generators.any?
|
49
|
+
|
50
|
+
generators.each do |generator|
|
51
|
+
fail "Invalid 'generator' #{generator}" unless Generator.exists?(generator)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def define_generators!
|
58
|
+
generators.each do |type|
|
59
|
+
desc "Generate #{type}"
|
60
|
+
task type => :environment do
|
61
|
+
Generator.perform(type)
|
62
|
+
end
|
63
|
+
|
64
|
+
define_generators_by_tag!(type)
|
65
|
+
define_customizer!
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def define_generators_by_tag!(type)
|
70
|
+
return unless Generator.supports?(type, :tags)
|
71
|
+
return unless tags.size > 1
|
72
|
+
|
73
|
+
namespace type do
|
74
|
+
tags.each do |tag|
|
75
|
+
desc "Generate #{type} for #{tag}"
|
76
|
+
task tag => :environment do
|
77
|
+
Generator.perform(type, tag)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def define_customizer!
|
84
|
+
return unless customize
|
54
85
|
|
55
|
-
|
56
|
-
|
86
|
+
desc "Customize Web UI"
|
87
|
+
task :customize => :environment do
|
88
|
+
Customizer.new.perform
|
57
89
|
end
|
58
90
|
end
|
59
91
|
end
|
data/lib/cabbage_doc/version.rb
CHANGED
data/lib/cabbage_doc/web.rb
CHANGED
@@ -36,12 +36,12 @@ module CabbageDoc
|
|
36
36
|
haml :index
|
37
37
|
end
|
38
38
|
|
39
|
-
get '/:id' do
|
39
|
+
get '/api/:id' do
|
40
40
|
response_by_id(params[:id])
|
41
41
|
end
|
42
42
|
|
43
|
-
post '/' do
|
44
|
-
response =
|
43
|
+
post '/api' do
|
44
|
+
response = config.request.call(post_request) if post_request.valid?
|
45
45
|
|
46
46
|
if response.is_a?(Response)
|
47
47
|
content_type :json
|
@@ -52,5 +52,19 @@ module CabbageDoc
|
|
52
52
|
halt 500
|
53
53
|
end
|
54
54
|
end
|
55
|
+
|
56
|
+
get '/:slug' do
|
57
|
+
slug = params[:slug].to_s.gsub(/[^a-z\-_]/, '')
|
58
|
+
filename = File.join(config.root, config.page_root, "#{slug}.html") unless slug.empty?
|
59
|
+
|
60
|
+
content = if !filename.empty? && File.exists?(filename)
|
61
|
+
File.read(filename)
|
62
|
+
else
|
63
|
+
status 404
|
64
|
+
"Page not found."
|
65
|
+
end
|
66
|
+
|
67
|
+
haml :page, layout: :page_layout, locals: { content: content }
|
68
|
+
end
|
55
69
|
end
|
56
70
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
require 'redcarpet'
|
2
|
+
|
1
3
|
module CabbageDoc
|
2
4
|
module WebHelper
|
3
5
|
def asset_path(path)
|
4
|
-
[request.path, path].join('/').gsub(/\/\/+/, '/')
|
6
|
+
[config.asset_path || request.path, path].join('/').gsub(/\/\/+/, '/')
|
5
7
|
end
|
6
8
|
|
7
9
|
def theme_path
|
@@ -13,8 +15,8 @@ module CabbageDoc
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def collection
|
16
|
-
if config.dev
|
17
|
-
|
18
|
+
if config.dev && config.auto_generate
|
19
|
+
Generator.perform(:all)
|
18
20
|
@_collection = nil
|
19
21
|
end
|
20
22
|
|
@@ -44,10 +46,18 @@ module CabbageDoc
|
|
44
46
|
auth.visibility.include?(o.visibility)
|
45
47
|
end
|
46
48
|
|
49
|
+
def tag_visible?(tag)
|
50
|
+
config.tags.size <= 1 || auth.visibility.include?(tag)
|
51
|
+
end
|
52
|
+
|
47
53
|
def format_visibility(o)
|
48
54
|
o.visibility.to_s.capitalize if o.visibility != VISIBILITY.first
|
49
55
|
end
|
50
56
|
|
57
|
+
def format_tag(tag)
|
58
|
+
tag.to_s.capitalize
|
59
|
+
end
|
60
|
+
|
51
61
|
def post_request
|
52
62
|
@_post_request ||= Request.new(request, collection)
|
53
63
|
end
|
@@ -1,9 +1,3 @@
|
|
1
|
-
body
|
2
|
-
{
|
3
|
-
margin: 0;
|
4
|
-
padding: 0;
|
5
|
-
}
|
6
|
-
|
7
1
|
pre, code, .authentication form
|
8
2
|
{
|
9
3
|
font-family: monospace;
|
@@ -32,18 +26,6 @@ input[type=button], input[type=submit]
|
|
32
26
|
min-width: 98px;
|
33
27
|
}
|
34
28
|
|
35
|
-
a, a:active, a:visited, a:hover
|
36
|
-
{
|
37
|
-
color: #000000;
|
38
|
-
text-decoration: none;
|
39
|
-
font-weight: bold;
|
40
|
-
}
|
41
|
-
|
42
|
-
a:hover
|
43
|
-
{
|
44
|
-
text-decoration: underline;
|
45
|
-
}
|
46
|
-
|
47
29
|
.hidden
|
48
30
|
{
|
49
31
|
display: none !important;
|
@@ -70,13 +52,7 @@ a:hover
|
|
70
52
|
float: right;
|
71
53
|
}
|
72
54
|
|
73
|
-
.
|
74
|
-
{
|
75
|
-
margin: 10px auto;
|
76
|
-
width: 1024px;
|
77
|
-
}
|
78
|
-
|
79
|
-
.welcome, .documentation, .authentication
|
55
|
+
.welcome, .api, .authentication
|
80
56
|
{
|
81
57
|
width: 100%;
|
82
58
|
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
body
|
2
|
+
{
|
3
|
+
margin: 0;
|
4
|
+
padding: 0;
|
5
|
+
}
|
6
|
+
|
7
|
+
a, a:active, a:visited, a:hover
|
8
|
+
{
|
9
|
+
color: #000000;
|
10
|
+
text-decoration: none;
|
11
|
+
font-weight: bold;
|
12
|
+
}
|
13
|
+
|
14
|
+
a:hover
|
15
|
+
{
|
16
|
+
text-decoration: underline;
|
17
|
+
}
|
18
|
+
|
19
|
+
.application, .page
|
20
|
+
{
|
21
|
+
margin: 10px auto;
|
22
|
+
width: 1024px;
|
23
|
+
}
|
@@ -116,8 +116,9 @@ $(document).ready(function()
|
|
116
116
|
|
117
117
|
var data = $('.authentication form').serializeArray().concat(form.serializeArray());
|
118
118
|
|
119
|
-
data.push({'name': '
|
120
|
-
data.push({'name': '
|
119
|
+
data.push({'name': '__method', 'value': form.attr('method') || ''});
|
120
|
+
data.push({'name': '__action', 'value': form.attr('action') || ''});
|
121
|
+
data.push({'name': '__tag', 'value': form.attr('data-tag') || 'api'});
|
121
122
|
|
122
123
|
data = $.grep(data, function(v, i)
|
123
124
|
{
|
@@ -144,7 +145,7 @@ $(document).ready(function()
|
|
144
145
|
|
145
146
|
setTimeout(function()
|
146
147
|
{
|
147
|
-
$.ajax(compose_path('/' + id), {
|
148
|
+
$.ajax(compose_path('/api/' + id), {
|
148
149
|
method: 'GET',
|
149
150
|
dataType: 'json',
|
150
151
|
complete: function(data)
|
@@ -158,7 +159,7 @@ $(document).ready(function()
|
|
158
159
|
}, 1000);
|
159
160
|
}
|
160
161
|
|
161
|
-
$.ajax(compose_path('/'), {
|
162
|
+
$.ajax(compose_path('/api'), {
|
162
163
|
data: $.param(data),
|
163
164
|
method: 'POST',
|
164
165
|
dataType: 'json',
|
@@ -167,7 +168,7 @@ $(document).ready(function()
|
|
167
168
|
var json = data.responseJSON || {};
|
168
169
|
|
169
170
|
if(data.status == 503 && typeof json.id != 'undefined')
|
170
|
-
retry_later(form, json.id,
|
171
|
+
retry_later(form, json.id, 5);
|
171
172
|
else
|
172
173
|
display_response(form, data);
|
173
174
|
}
|
data/web/views/action.haml
CHANGED
@@ -6,10 +6,10 @@
|
|
6
6
|
%span= " : #{action.label}"
|
7
7
|
%span.visibility= format_visibility(action)
|
8
8
|
.clear
|
9
|
-
%form.hidden{ action: action.path, method: action.method }
|
9
|
+
%form.hidden{ action: action.path, method: action.method, :'data-tag' => tag }
|
10
10
|
- if action.description
|
11
11
|
.description= markdown.render(action.description)
|
12
|
-
- if action.visibility
|
12
|
+
- if %i(unreleased beta).include?(action.visibility)
|
13
13
|
.warning= 'This API is still under development and will continue to evolve.'
|
14
14
|
- if config.examples && action.examples.any?
|
15
15
|
.examples
|
@@ -24,4 +24,4 @@
|
|
24
24
|
%th='Description'
|
25
25
|
- action.parameters.each do |parameter|
|
26
26
|
= haml :parameter, locals: { parameter: parameter }
|
27
|
-
|
27
|
+
= haml :response
|
data/web/views/api.haml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
.controllers
|
2
|
+
- if config.tags.size > 1
|
3
|
+
- grouped = collection.group_by(&:tag)
|
4
|
+
- config.tags.each { |tag| grouped.delete(tag) unless tag_visible?(tag) }
|
5
|
+
- if grouped.size > 1
|
6
|
+
- collection.group_by(&:tag).each do |tag, controllers|
|
7
|
+
.tag
|
8
|
+
.resource
|
9
|
+
= format_tag(tag)
|
10
|
+
= haml :controllers, locals: { controllers: controllers }
|
11
|
+
- else
|
12
|
+
= haml :controllers, locals: { controllers: grouped.values.first }
|
13
|
+
- else
|
14
|
+
= haml :controllers, locals: { controllers: collection }
|
data/web/views/controller.haml
CHANGED
data/web/views/index.haml
CHANGED
data/web/views/layout.haml
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
%html
|
3
3
|
%head
|
4
4
|
%link{ rel: :stylesheet, href: theme_path, type: 'text/css' }
|
5
|
+
%link{ rel: :stylesheet, href: asset_path('css/base.css'), type: 'text/css' }
|
5
6
|
%link{ rel: :stylesheet, href: asset_path('css/application.css'), type: 'text/css' }
|
6
7
|
%script{ src: asset_path('js/jquery-1.12.3.min.js'), type: 'text/javascript' }
|
7
8
|
%script{ src: asset_path('js/highlight.min.js'), type: 'text/javascript' }
|
data/web/views/page.haml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
= markdown.render(content) unless content.empty?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cabbage_doc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mihail Szabolcs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redcarpet
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: haml
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: sinatra
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -139,12 +153,13 @@ files:
|
|
139
153
|
- lib/cabbage_doc/controller.rb
|
140
154
|
- lib/cabbage_doc/customizer.rb
|
141
155
|
- lib/cabbage_doc/example.rb
|
156
|
+
- lib/cabbage_doc/generator.rb
|
157
|
+
- lib/cabbage_doc/generators/api.rb
|
158
|
+
- lib/cabbage_doc/generators/pages.rb
|
142
159
|
- lib/cabbage_doc/parameter.rb
|
143
160
|
- lib/cabbage_doc/params.rb
|
144
161
|
- lib/cabbage_doc/parser.rb
|
145
162
|
- lib/cabbage_doc/path.rb
|
146
|
-
- lib/cabbage_doc/processor.rb
|
147
|
-
- lib/cabbage_doc/processors/documentation.rb
|
148
163
|
- lib/cabbage_doc/request.rb
|
149
164
|
- lib/cabbage_doc/response.rb
|
150
165
|
- lib/cabbage_doc/singleton.rb
|
@@ -155,6 +170,7 @@ files:
|
|
155
170
|
- lib/cabbage_doc/worker.rb
|
156
171
|
- web/helpers/helper.rb
|
157
172
|
- web/public/css/application.css
|
173
|
+
- web/public/css/base.css
|
158
174
|
- web/public/css/highlight/agate.css
|
159
175
|
- web/public/css/highlight/androidstudio.css
|
160
176
|
- web/public/css/highlight/arduino-light.css
|
@@ -194,14 +210,17 @@ files:
|
|
194
210
|
- web/public/js/highlight.min.js
|
195
211
|
- web/public/js/jquery-1.12.3.min.js
|
196
212
|
- web/views/action.haml
|
213
|
+
- web/views/api.haml
|
197
214
|
- web/views/array.haml
|
198
215
|
- web/views/authentication.haml
|
199
216
|
- web/views/controller.haml
|
200
|
-
- web/views/
|
217
|
+
- web/views/controllers.haml
|
201
218
|
- web/views/enumeration.haml
|
202
219
|
- web/views/example.haml
|
203
220
|
- web/views/index.haml
|
204
221
|
- web/views/layout.haml
|
222
|
+
- web/views/page.haml
|
223
|
+
- web/views/page_layout.haml
|
205
224
|
- web/views/parameter.haml
|
206
225
|
- web/views/response.haml
|
207
226
|
- web/views/text.haml
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module CabbageDoc
|
2
|
-
module Processors
|
3
|
-
class Documentation < Processor
|
4
|
-
priority :high
|
5
|
-
|
6
|
-
def perform
|
7
|
-
collection.clear!
|
8
|
-
|
9
|
-
config.controllers.call.each do |filename|
|
10
|
-
collection.parse!(filename)
|
11
|
-
end
|
12
|
-
|
13
|
-
collection.save!
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|