dictum 0.0.3 → 0.0.4
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 +2 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +1 -1
- data/README.md +14 -9
- data/TODO.md +1 -3
- data/dictum.gemspec +3 -1
- data/lib/dictum.rb +7 -2
- data/lib/dictum/documenter.rb +5 -1
- data/lib/dictum/html_helpers.rb +54 -34
- data/lib/dictum/html_writer.rb +48 -59
- data/lib/dictum/markdown_writer.rb +2 -3
- data/lib/dictum/version.rb +1 -1
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 217d2599c6e42803dae17c91e5f912b62c9c1c69
|
4
|
+
data.tar.gz: 67ea4dea1683a6d22bfcb6a83ad6bc39b981a235
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0d2f490887e718e421ead994f06fb3dd5603465aceb15773ed673ed63a49997ba77d18a52eda092cef8dbed17efb884508b179e78ae7a6508d90ecd66c9508c
|
7
|
+
data.tar.gz: 749835247251aa4c2e79d273d50ae6e47f1de9b79ee8e78d18febdfa46477a79868465d219bc91001b2011ef65806d5ef2ed4c326c97b62a453abbe6cb232b06
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# Dictum - Document your Rails APIs
|
2
2
|
[](https://badge.fury.io/rb/dictum)
|
3
|
-
[](https://gemnasium.com/github.com/Wolox/dictum)
|
4
|
+
[](https://travis-ci.org/Wolox/dictum)
|
5
|
+
[](https://codeclimate.com/github/Wolox/dictum)
|
6
|
+
[](https://codeclimate.com/github/Wolox/dictum/coverage)
|
7
|
+
[](https://codeclimate.com/github/Wolox/dictum)
|
8
|
+
[](http://inch-ci.org/github/Wolox/dictum)
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -179,7 +179,6 @@ RSpec.configure do |config|
|
|
179
179
|
end
|
180
180
|
end
|
181
181
|
end
|
182
|
-
end
|
183
182
|
```
|
184
183
|
|
185
184
|
```ruby
|
@@ -225,7 +224,7 @@ YourApp::Application.routes.draw do
|
|
225
224
|
#
|
226
225
|
# Other routes defined
|
227
226
|
#
|
228
|
-
|
227
|
+
|
229
228
|
doc_paths = Dir["#{Rails.root.join('app', 'views', 'docs')}/*"].each do |path|
|
230
229
|
resource = path.split('/').last.gsub('.html', '')
|
231
230
|
get "/docs/#{resource}", to: "docs##{resource}"
|
@@ -245,9 +244,15 @@ Of course you will need to have a controller for this, in this case one named 'd
|
|
245
244
|
6. Push your branch (`git push origin my-new-feature`)
|
246
245
|
7. Create a new Pull Request
|
247
246
|
|
247
|
+
## About ##
|
248
|
+
|
249
|
+
This project is maintained by [Alejandro Bezdjian](https://github.com/alebian) and it was written by [Wolox](http://www.wolox.com.ar).
|
250
|
+
|
251
|
+

|
252
|
+
|
248
253
|
## License
|
249
254
|
|
250
|
-
**Dictum** is available under the MIT [license](https://raw.githubusercontent.com/
|
255
|
+
**Dictum** is available under the MIT [license](https://raw.githubusercontent.com/Wolox/dictum/master/LICENSE.md).
|
251
256
|
|
252
257
|
Copyright (c) 2016 Alejandro Bezdjian, aka alebian
|
253
258
|
|
data/TODO.md
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# List of TODOs
|
2
|
-
- Add some tests
|
3
2
|
- Don't generate documentation while running normal tests
|
4
|
-
- HTML
|
5
|
-
- Dir.tempdir problems outside Rails
|
3
|
+
- Improve HTML style and generator
|
6
4
|
- Try it for Unit Test
|
7
5
|
- Make it more general, not only for REST APIs
|
data/dictum.gemspec
CHANGED
@@ -14,11 +14,13 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.platform = Gem::Platform::RUBY
|
15
15
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec)/}) }
|
16
16
|
spec.require_paths = ['lib']
|
17
|
-
spec.homepage = 'https://github.com/
|
17
|
+
spec.homepage = 'https://github.com/Wolox/dictum'
|
18
18
|
spec.license = 'MIT'
|
19
19
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec)/})
|
21
21
|
|
22
|
+
spec.add_dependency 'htmlbeautifier', '~> 1.1', '>= 1.1.1'
|
23
|
+
|
22
24
|
spec.add_development_dependency 'bundler', '>= 1.3.0', '< 2.0'
|
23
25
|
spec.add_development_dependency 'rspec', '~> 3.4', '>= 3.4.0'
|
24
26
|
spec.add_development_dependency 'byebug', '~> 8.0', '>= 8.0.0' if RUBY_VERSION >= '2.0.0'
|
data/lib/dictum.rb
CHANGED
@@ -3,14 +3,15 @@ require 'dictum/documenter'
|
|
3
3
|
require 'dictum/markdown_writer'
|
4
4
|
require 'dictum/html_writer'
|
5
5
|
require 'dictum/html_helpers'
|
6
|
+
require 'tmpdir'
|
6
7
|
|
7
8
|
module Dictum
|
8
9
|
load 'tasks/dictum.rake' if defined?(Rails)
|
9
10
|
|
10
11
|
@config = {
|
11
12
|
output_format: :markdown,
|
12
|
-
output_path:
|
13
|
-
root_path:
|
13
|
+
output_path: "#{Dir.tmpdir}/docs",
|
14
|
+
root_path: Dir.tmpdir,
|
14
15
|
test_suite: :rspec,
|
15
16
|
output_filename: 'Documentation'
|
16
17
|
}
|
@@ -39,6 +40,10 @@ module Dictum
|
|
39
40
|
@config[:output_filename] = file
|
40
41
|
end
|
41
42
|
|
43
|
+
def self.config
|
44
|
+
@config
|
45
|
+
end
|
46
|
+
|
42
47
|
##
|
43
48
|
# Method used to create a new resource
|
44
49
|
#
|
data/lib/dictum/documenter.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'singleton'
|
2
|
+
require 'tmpdir'
|
2
3
|
|
3
4
|
module Dictum
|
4
5
|
##
|
@@ -6,14 +7,17 @@ module Dictum
|
|
6
7
|
#
|
7
8
|
class Documenter
|
8
9
|
include Singleton
|
10
|
+
|
9
11
|
attr_reader :resources, :tempfile_path
|
12
|
+
TEMPFILE_NAME = 'dictum_temp.json'.freeze
|
10
13
|
|
11
14
|
def initialize
|
12
15
|
@resources = {}
|
13
|
-
@tempfile_path =
|
16
|
+
@tempfile_path = "#{Dir.tmpdir}/#{TEMPFILE_NAME}"
|
14
17
|
end
|
15
18
|
|
16
19
|
def resource(arguments = {})
|
20
|
+
return if arguments.nil?
|
17
21
|
name = arguments[:name]
|
18
22
|
return if name.nil?
|
19
23
|
@resources[name] ||= {}
|
data/lib/dictum/html_helpers.rb
CHANGED
@@ -6,79 +6,99 @@ module Dictum
|
|
6
6
|
PRETTIFY = 'https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js'.freeze
|
7
7
|
|
8
8
|
class << self
|
9
|
-
def
|
10
|
-
|
11
|
-
"\n<style>\n#{page_css}\n</style>\n</head>\n<body>\n"
|
9
|
+
def build
|
10
|
+
yield self
|
12
11
|
end
|
13
12
|
|
14
|
-
def
|
13
|
+
def html_header(title, body_content)
|
14
|
+
"<!DOCTYPE html>\n<html>\n<head>\n<title>#{title}</title>\n#{external_css(BOOTSTRAP_CSS)}"\
|
15
|
+
"\n<style>\n#{page_css}\n</style>\n</head>\n<body>\n#{body_content}" \
|
15
16
|
"#{script(JQUERY)}\n#{script(BOOTSTRAP_JS)}\n#{script(PRETTIFY)}\n</body>\n</html>"
|
16
17
|
end
|
17
18
|
|
18
|
-
def
|
19
|
-
''
|
20
|
-
end
|
21
|
-
|
22
|
-
def container
|
23
|
-
"<div class='container-fluid'>\n"
|
24
|
-
end
|
25
|
-
|
26
|
-
def container_end
|
27
|
-
'</div>'
|
19
|
+
def container(content)
|
20
|
+
tag('div', "\n#{content}\n", class: 'container-fluid')
|
28
21
|
end
|
29
22
|
|
30
|
-
def row
|
31
|
-
|
23
|
+
def row(content)
|
24
|
+
internal_div = tag('div', "\n#{content}\n", class: 'col-md-8 col-md-offset-2')
|
25
|
+
tag('div', "\n#{internal_div}", class: 'row')
|
32
26
|
end
|
33
27
|
|
34
|
-
def
|
35
|
-
|
28
|
+
def page_css
|
29
|
+
''
|
36
30
|
end
|
37
31
|
|
38
|
-
def script(
|
39
|
-
|
32
|
+
def script(script_path)
|
33
|
+
return '' unless script_path
|
34
|
+
tag('script', nil, src: script_path)
|
40
35
|
end
|
41
36
|
|
42
|
-
def external_css(
|
43
|
-
|
37
|
+
def external_css(css_path)
|
38
|
+
return '' unless css_path
|
39
|
+
"<link rel='stylesheet' href='#{css_path}' />\n"
|
44
40
|
end
|
45
41
|
|
46
42
|
def unordered_list(elements)
|
43
|
+
return "<ul>\n</ul>\n" unless elements
|
47
44
|
answer = "<ul>\n"
|
48
45
|
elements.each do |element|
|
49
46
|
answer += "<li><a href='#{element.downcase}.html'>#{element}</a></li>\n"
|
50
47
|
end
|
51
|
-
answer +=
|
48
|
+
answer += "</ul>\n"
|
49
|
+
end
|
50
|
+
|
51
|
+
def link(href, content)
|
52
|
+
tag('a', content, href: href)
|
52
53
|
end
|
53
54
|
|
54
55
|
def title(text, html_class = nil)
|
55
|
-
"<h1
|
56
|
+
return "<h1>#{text}</h1>\n" unless html_class
|
57
|
+
tag('h1', text, class: html_class)
|
56
58
|
end
|
57
59
|
|
58
60
|
def subtitle(text, html_class = nil)
|
59
|
-
"<h3
|
61
|
+
return "<h3>#{text}</h3>\n" unless html_class
|
62
|
+
tag('h3', text, class: html_class)
|
63
|
+
end
|
64
|
+
|
65
|
+
def sub_subtitle(text, html_class = nil)
|
66
|
+
return "<h4>#{text}</h4>\n" unless html_class
|
67
|
+
tag('h4', text, class: html_class)
|
60
68
|
end
|
61
69
|
|
62
70
|
def paragraph(text, html_class = nil)
|
63
|
-
"<p
|
71
|
+
return "<p>#{text}</p>\n" unless html_class
|
72
|
+
tag('p', text, class: html_class)
|
64
73
|
end
|
65
74
|
|
66
75
|
def button(text, glyphicon = nil)
|
67
|
-
|
68
|
-
|
69
|
-
|
76
|
+
span = tag('span', text, class: "glyphicon #{glyphicon}", 'aria-hidden' => 'true')
|
77
|
+
button = tag('button', "\n#{span}", 'type' => 'button',
|
78
|
+
'class' => 'btn btn-primary back',
|
79
|
+
'aria-label' => 'Left Align')
|
80
|
+
tag('a', "\n#{button}", href: 'index.html')
|
70
81
|
end
|
71
82
|
|
72
83
|
def code_block(title, json)
|
73
|
-
|
84
|
+
return '' unless json
|
85
|
+
return code(json) unless title
|
86
|
+
"#{sub_subtitle(title)}#{code(json)}"
|
74
87
|
end
|
75
88
|
|
76
|
-
def
|
77
|
-
|
89
|
+
def code(json)
|
90
|
+
return '' unless json
|
91
|
+
tag('pre', json, class: 'prettyprint')
|
78
92
|
end
|
79
93
|
|
80
|
-
def
|
81
|
-
|
94
|
+
def tag(name, content, attributes = {})
|
95
|
+
return '' unless name
|
96
|
+
answer = "<#{name}"
|
97
|
+
attributes.each do |key, value|
|
98
|
+
answer += " #{key}='#{value}'"
|
99
|
+
end
|
100
|
+
answer += ">#{content}"
|
101
|
+
answer += "</#{name}>\n"
|
82
102
|
end
|
83
103
|
end
|
84
104
|
end
|
data/lib/dictum/html_writer.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'html_helpers'
|
2
2
|
require 'json'
|
3
|
+
require 'htmlbeautifier'
|
3
4
|
|
4
5
|
module Dictum
|
5
6
|
class HtmlWriter
|
@@ -20,89 +21,77 @@ module Dictum
|
|
20
21
|
|
21
22
|
private
|
22
23
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
file.puts(HtmlHelpers.container)
|
27
|
-
file.puts(HtmlHelpers.row)
|
28
|
-
end
|
29
|
-
|
30
|
-
def write_index_footer(file)
|
31
|
-
return unless file
|
32
|
-
file.puts(HtmlHelpers.row_end)
|
33
|
-
file.puts(HtmlHelpers.container_end)
|
34
|
-
file.puts(HtmlHelpers.html_footer)
|
35
|
-
end
|
36
|
-
|
37
|
-
def write_index
|
38
|
-
index = File.open("#{output_dir}/index.html", 'w+')
|
39
|
-
write_index_header(index)
|
40
|
-
index.puts("<div class='jumbotron'>\n#{HtmlHelpers.title('Index', 'title')}\n</div>")
|
41
|
-
index.puts(HtmlHelpers.unordered_list(temp_json.keys))
|
42
|
-
write_index_footer(index)
|
24
|
+
def write_to_file(file_path, content)
|
25
|
+
index = File.open(file_path, 'w+')
|
26
|
+
index.puts(HtmlBeautifier.beautify(content))
|
43
27
|
index.close
|
44
28
|
end
|
45
29
|
|
46
|
-
def
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
file.puts(HtmlHelpers.row_end)
|
55
|
-
file.puts(HtmlHelpers.row)
|
56
|
-
file.puts(HtmlHelpers.button('Back', 'glyphicon-menu-left'))
|
57
|
-
write_index_footer(file)
|
30
|
+
def write_index
|
31
|
+
html = HtmlHelpers.build do |b|
|
32
|
+
content = "<div class='jumbotron'>\n#{HtmlHelpers.title('Index', 'title')}\n</div>\n"
|
33
|
+
content += b.unordered_list(temp_json.keys)
|
34
|
+
container = b.container(b.row(content))
|
35
|
+
b.html_header(output_title, container)
|
36
|
+
end
|
37
|
+
write_to_file("#{output_dir}/index.html", html)
|
58
38
|
end
|
59
39
|
|
60
40
|
def write_pages
|
61
41
|
temp_json.each do |resource_name, information|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
write_endpoints(information['endpoints'], file)
|
42
|
+
write_page(resource_name, information)
|
43
|
+
end
|
44
|
+
end
|
66
45
|
|
67
|
-
|
68
|
-
|
46
|
+
def write_page(resource_name, information)
|
47
|
+
html = HtmlHelpers.build do |b|
|
48
|
+
content = resource_header_and_endpoints(
|
49
|
+
resource_name, information['description'], information['endpoints'], b
|
50
|
+
)
|
51
|
+
container = b.container(b.row(content) + b.row(b.button('Back', 'glyphicon-menu-left')))
|
52
|
+
b.html_header(output_title, container)
|
69
53
|
end
|
54
|
+
write_to_file("#{output_dir}/#{resource_name.downcase}.html", html)
|
55
|
+
end
|
56
|
+
|
57
|
+
def resource_header_and_endpoints(resource_name, description, endpoints, builder)
|
58
|
+
builder.title(resource_name, 'title') + builder.paragraph(description) +
|
59
|
+
write_endpoints(endpoints, builder)
|
70
60
|
end
|
71
61
|
|
72
|
-
def write_endpoints(endpoints,
|
62
|
+
def write_endpoints(endpoints, builder)
|
63
|
+
answer = ''
|
73
64
|
endpoints.each do |endpoint|
|
74
|
-
|
75
|
-
|
76
|
-
write_request_parameters(endpoint,
|
77
|
-
write_response(endpoint,
|
65
|
+
answer += builder.subtitle("#{endpoint['http_verb']} #{endpoint['endpoint']}")
|
66
|
+
answer += builder.paragraph(endpoint['description'])
|
67
|
+
answer += write_request_parameters(endpoint, builder)
|
68
|
+
answer += write_response(endpoint, builder)
|
78
69
|
end
|
70
|
+
answer
|
79
71
|
end
|
80
72
|
|
81
|
-
def write_request_parameters(endpoint,
|
82
|
-
write_codeblock('Request headers',
|
83
|
-
|
84
|
-
|
85
|
-
write_codeblock('Request body parameters',
|
86
|
-
JSON.pretty_generate(endpoint['request_body_parameters']), file)
|
73
|
+
def write_request_parameters(endpoint, builder)
|
74
|
+
write_codeblock('Request headers', endpoint['request_headers'], builder) +
|
75
|
+
write_codeblock('Request path parameters', endpoint['request_path_parameters'], builder) +
|
76
|
+
write_codeblock('Request body parameters', endpoint['request_body_parameters'], builder)
|
87
77
|
end
|
88
78
|
|
89
|
-
def write_response(endpoint,
|
90
|
-
|
91
|
-
write_codeblock(
|
92
|
-
'Response headers',
|
93
|
-
JSON.pretty_generate(endpoint['response_headers']),
|
94
|
-
file
|
79
|
+
def write_response(endpoint, builder)
|
80
|
+
answer = builder.code_block('Status', endpoint['response_status'])
|
81
|
+
answer += write_codeblock(
|
82
|
+
'Response headers', endpoint['response_headers'], builder
|
95
83
|
) if endpoint['response_headers']
|
96
84
|
|
97
85
|
if endpoint['response_body']
|
98
86
|
param = (endpoint['response_body'] == 'no_content') ? {} : endpoint['response_body']
|
99
|
-
write_codeblock('Response body',
|
87
|
+
answer += write_codeblock('Response body', param, builder)
|
100
88
|
end
|
89
|
+
answer
|
101
90
|
end
|
102
91
|
|
103
|
-
def write_codeblock(text, json,
|
104
|
-
return unless text && json &&
|
105
|
-
|
92
|
+
def write_codeblock(text, json, builder)
|
93
|
+
return unless text && json && builder
|
94
|
+
builder.code_block(text, JSON.pretty_generate(json))
|
106
95
|
end
|
107
96
|
end
|
108
97
|
end
|
@@ -16,7 +16,6 @@ module Dictum
|
|
16
16
|
write_index
|
17
17
|
write_temp_path
|
18
18
|
output_file.close
|
19
|
-
File.delete(temp_path) if File.exist?(temp_path)
|
20
19
|
end
|
21
20
|
|
22
21
|
private
|
@@ -59,13 +58,13 @@ module Dictum
|
|
59
58
|
end
|
60
59
|
|
61
60
|
def print_subsubtitle(subtitle, contents)
|
62
|
-
return if !subtitle
|
61
|
+
return if !subtitle || !contents
|
63
62
|
output_file.puts "\#\#\# #{subtitle}:"
|
64
63
|
output_file.puts "#{contents}\n\n"
|
65
64
|
end
|
66
65
|
|
67
66
|
def print_subsubtitle_json(subtitle, contents)
|
68
|
-
return
|
67
|
+
return unless subtitle && contents
|
69
68
|
output_file.puts "\#\#\# #{subtitle}:"
|
70
69
|
output_file.puts "```json\n#{JSON.pretty_generate(contents)}\n```\n\n"
|
71
70
|
end
|
data/lib/dictum/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dictum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alejandro Bezdjian
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: htmlbeautifier
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.1.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.1.1
|
13
33
|
- !ruby/object:Gem::Dependency
|
14
34
|
name: bundler
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -113,7 +133,7 @@ files:
|
|
113
133
|
- lib/dictum/markdown_writer.rb
|
114
134
|
- lib/dictum/version.rb
|
115
135
|
- lib/tasks/dictum.rake
|
116
|
-
homepage: https://github.com/
|
136
|
+
homepage: https://github.com/Wolox/dictum
|
117
137
|
licenses:
|
118
138
|
- MIT
|
119
139
|
metadata: {}
|
@@ -133,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
153
|
version: '0'
|
134
154
|
requirements: []
|
135
155
|
rubyforge_project:
|
136
|
-
rubygems_version: 2.
|
156
|
+
rubygems_version: 2.5.1
|
137
157
|
signing_key:
|
138
158
|
specification_version: 4
|
139
159
|
summary: Document your APIs.
|