lurker 0.6.9 → 0.6.10
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
- checksums.yaml.gz.sig +1 -2
- data.tar.gz.sig +0 -0
- data/README.md +8 -1
- data/lib/lurker.rb +9 -1
- data/lib/lurker/cli.rb +148 -129
- data/lib/lurker/endpoint.rb +7 -3
- data/lib/lurker/json/schema.rb +12 -3
- data/lib/lurker/json/{writter.rb → writer.rb} +2 -2
- data/lib/lurker/presenters/base_presenter.rb +9 -34
- data/lib/lurker/presenters/endpoint_presenter.rb +16 -6
- data/lib/lurker/presenters/service_presenter.rb +29 -5
- data/lib/lurker/rendering_controller.rb +14 -7
- data/lib/lurker/service.rb +18 -12
- data/lib/lurker/templates/documentation.md.tt +1 -0
- data/lib/lurker/templates/javascripts/lurker.js +1 -1
- data/lib/lurker/templates/layouts/application.html.erb +54 -57
- data/lib/lurker/templates/layouts/print.html.erb +29 -0
- data/lib/lurker/templates/lurker/rendering/_endpoint.html.erb +36 -0
- data/lib/lurker/templates/lurker/rendering/_service.html.erb +7 -0
- data/lib/lurker/templates/lurker/rendering/_submit_form.html.erb +16 -16
- data/lib/lurker/templates/lurker/rendering/all.html.erb +5 -0
- data/lib/lurker/templates/lurker/rendering/index.html.erb +1 -10
- data/lib/lurker/templates/lurker/rendering/show.html.erb +1 -37
- data/lib/lurker/templates/public/application.css +1 -1
- data/lib/lurker/templates/public/application.js +1 -1
- data/lib/lurker/templates/stylesheets/application.scss +3 -0
- data/lib/lurker/version.rb +1 -1
- data/tasks/build.rake +2 -2
- data/tasks/generate.rake +2 -0
- data/templates/lurker_app.rb +0 -1
- metadata +8 -4
- metadata.gz.sig +0 -0
- data/lib/lurker/templates/meta_service.md.erb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb9c0414b141e2d48b9c7a6d03be6e671a6ad3ed
|
4
|
+
data.tar.gz: 777ba4fb742083bfaabeb5c912be901ae51f9bfc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad1be4d40f3a1558527e61d2bce3b22eb9050f8264189b54d5a2346763a86c7559dd0b6c245ec71a5a8a8100f14d62245d30236d227af8ba91e6de0cb5fcf799
|
7
|
+
data.tar.gz: cd34824f79c859a1cc27eea9a0d7b9f23af8f58bcfe680037fae0a151c6a49d593f3c0990677cc8d9288d08e0d9e4ca5dba112495039f96b306d33a766f0eee7
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
�������j��ML�l،��x�gy�_��mp0(�
|
1
|
+
Ҕ�+Il�$�0٫#�bA�������j�q����0��������O§�i(����YN/���:��/+�Z�m���5/(��d��2Zk1��p�Ùo|J+w�.�[�\����fE*�^��bs�'����$ݝ�_�u�� ���v6M�p�f�Q�QϞ���d��O��6��!���7������#�q�`˼9����㣸А��5���~�x�<8�V�l��5۩�_�k�BL��uS���������
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -92,6 +92,13 @@ The generation of live-documentation is pretty simple:
|
|
92
92
|
|
93
93
|
For different document root or serving URL prefix use `-o` and `-u` options accordingly.
|
94
94
|
|
95
|
+
If you want to provide additional documentation for your API (and you probably should),
|
96
|
+
you can use separate Markdown files in the schema folder. To generate documentation
|
97
|
+
stubs for the current schema:
|
98
|
+
|
99
|
+
bin/lurker init_docs # generate documentation stubs for the current schema
|
100
|
+
|
101
|
+
|
95
102
|
Let's run your `rails s` and visit [http://localhost:3000/lurker/](http://localhost:3000/lurker/)
|
96
103
|
(or see [demo][demo_app2] for example)
|
97
104
|
|
@@ -217,7 +224,7 @@ This gem is heavily inspired by them. Thanks, @square & @fredwu
|
|
217
224
|
Also thanks to
|
218
225
|
|
219
226
|
- [Andrey Deryabin][aderyabin] for advice
|
220
|
-
- [React.js][reactjs] for
|
227
|
+
- [React.js][reactjs] for reactive UI
|
221
228
|
- [highlight.js][hljs] for syntax highlighting
|
222
229
|
|
223
230
|
[aderyabin]: https://twitter.com/aderyabin
|
data/lib/lurker.rb
CHANGED
@@ -28,6 +28,14 @@ module Lurker
|
|
28
28
|
@service_path || DEFAULT_SERVICE_PATH
|
29
29
|
end
|
30
30
|
|
31
|
+
def self.valid_service_path?
|
32
|
+
Dir.exist? service_path
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.service
|
36
|
+
@service ||= Lurker::Service.new(service_path)
|
37
|
+
end
|
38
|
+
|
31
39
|
def self.decide_success_with(&block)
|
32
40
|
@success_block = block
|
33
41
|
end
|
@@ -65,7 +73,7 @@ require 'lurker/presenters/schema_presenter'
|
|
65
73
|
require 'lurker/presenters/response_code_presenter'
|
66
74
|
require 'lurker/json'
|
67
75
|
require 'lurker/json/reader'
|
68
|
-
require 'lurker/json/
|
76
|
+
require 'lurker/json/writer'
|
69
77
|
require 'lurker/json/orderer'
|
70
78
|
require 'lurker/json/parser'
|
71
79
|
require 'lurker/json/parser/expertise'
|
data/lib/lurker/cli.rb
CHANGED
@@ -5,6 +5,9 @@ require 'lurker'
|
|
5
5
|
require 'active_support/inflector'
|
6
6
|
|
7
7
|
module Lurker
|
8
|
+
BUNDLED_TEMPLATES_PATH = Pathname.new('../templates').expand_path(__FILE__)
|
9
|
+
BUNDLED_ASSETS_PATH = Pathname.new('../templates/public').expand_path(__FILE__)
|
10
|
+
|
8
11
|
# A Thor::Error to be thrown when an lurker directory is not found
|
9
12
|
class NotFound < Thor::Error; end
|
10
13
|
|
@@ -12,140 +15,124 @@ module Lurker
|
|
12
15
|
class Cli < Thor
|
13
16
|
include Thor::Actions
|
14
17
|
|
15
|
-
attr_accessor :
|
18
|
+
attr_accessor :content
|
19
|
+
|
20
|
+
def self.templates_root
|
21
|
+
options[:template].present? ? Pathname.new(options[:templates]).expand_path : Lurker::BUNDLED_TEMPLATES_PATH
|
22
|
+
end
|
16
23
|
|
17
|
-
def self.
|
18
|
-
|
24
|
+
def self.assets_root
|
25
|
+
options[:assets].present? ? Pathname.new(options[:assets]).expand_path : Lurker::BUNDLED_ASSETS_PATH
|
19
26
|
end
|
20
27
|
|
21
|
-
|
22
|
-
|
28
|
+
source_root(templates_root)
|
29
|
+
|
30
|
+
desc 'init_docs [LURKER_PATH]', 'Create documentation stubs for service and endpoints'
|
31
|
+
|
32
|
+
def init_docs(lurker_path=Lurker::DEFAULT_SERVICE_PATH)
|
33
|
+
say_status nil, 'Creating documentation stubs'
|
34
|
+
|
35
|
+
setup_schema_root! lurker_path
|
36
|
+
|
37
|
+
schemas = Lurker.service.endpoints.map(&:schema) << Lurker.service.schema
|
38
|
+
schemas.each do |schema|
|
39
|
+
rel_path = Pathname.new(schema.documentation_uri).relative_path_from(Pathname.getwd)
|
40
|
+
template 'documentation.md.tt', schema.documentation_uri, skip: true, path: rel_path
|
41
|
+
end
|
23
42
|
end
|
24
43
|
|
25
|
-
desc
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
44
|
+
desc 'convert [LURKER_PATH]', 'Convert lurker to HTML'
|
45
|
+
option :rails, type: :boolean, desc: 'Includes Rails environment'
|
46
|
+
option :exclude, aliases: '-e', desc: 'Select endpoints by given regexp, if NOT matching prefix'
|
47
|
+
option :select, aliases: '-s', desc: 'Select endpoints by given regexp, matching prefix'
|
48
|
+
option :output, aliases: '-o', desc: 'Output path', default: 'public'
|
49
|
+
option :url_base_path, aliases: '-u', desc: 'URL base path', default: Lurker::DEFAULT_URL_BASE
|
50
|
+
option :templates, aliases: '-t', desc: 'Template overrides path'
|
51
|
+
option :assets, aliases: '-a', desc: 'Assets overrides path'
|
52
|
+
option :format, aliases: '-f', desc: 'Format in html or pdf, defaults to html', default: 'html'
|
53
|
+
option :content, aliases: '-c', desc: 'Content to be rendered into html-docs main page'
|
54
|
+
|
34
55
|
def convert(lurker_path=Lurker::DEFAULT_SERVICE_PATH)
|
35
56
|
say_status nil, "Converting lurker to #{options[:format]}"
|
36
57
|
|
37
|
-
|
38
|
-
|
39
|
-
raise Lurker::NotFound.new(origin_path) unless has_valid_origin?
|
40
|
-
say_status :using, lurker_path
|
41
|
-
|
42
|
-
FileUtils.mkdir_p(output_path)
|
43
|
-
say_status :inside, output_path
|
58
|
+
setup_schema_root! lurker_path
|
59
|
+
require "#{Dir.pwd}/config/environment" if options[:rails]
|
44
60
|
|
45
|
-
|
46
|
-
|
61
|
+
# for backward compatibility
|
62
|
+
if options[:content]
|
63
|
+
Lurker.service.documentation = open(File.expand_path(options[:content])).read
|
47
64
|
end
|
48
65
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
66
|
+
setup_rendering_engine!
|
67
|
+
|
68
|
+
inside(output_path) do
|
69
|
+
say_status :inside, output_path
|
70
|
+
prepare_assets!
|
71
|
+
if options[:format] == 'pdf'
|
72
|
+
convert_to_pdf
|
73
|
+
else
|
74
|
+
convert_to_html
|
75
|
+
end
|
76
|
+
cleanup_assets!
|
53
77
|
end
|
54
78
|
end
|
55
79
|
|
56
80
|
no_tasks do
|
57
81
|
def convert_to_pdf
|
58
82
|
Lurker.safe_require('pdfkit')
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
html = "<html><body>"
|
63
|
-
service_presenter.endpoints.each do |endpoint_prefix_group|
|
64
|
-
endpoint_prefix_group.each do |endpoint_presenter|
|
65
|
-
html << endpoint_presenter.to_html(layout: false)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
html << "</body></html>"
|
69
|
-
kit = PDFKit.new(html, :page_size => 'Letter')
|
70
|
-
kit.stylesheets << css
|
71
|
-
url_name = ActiveSupport::Inflector.parameterize(service_presenter.name, '_')
|
72
|
-
create_file("#{url_name}.pdf", kit.to_pdf, force: true)
|
73
|
-
end
|
74
|
-
end
|
83
|
+
kit = PDFKit.new(service_presenter.to_print)
|
84
|
+
kit.stylesheets << assets['application.css']
|
85
|
+
create_file "#{service_presenter.url_name}.pdf", kit.to_pdf, force: true
|
75
86
|
end
|
76
87
|
|
77
88
|
def convert_to_html
|
78
|
-
|
79
|
-
# js, css, fonts
|
80
|
-
static = []
|
81
|
-
Dir["#{self.class.precompiled_static_root}/*"].each do |fname|
|
82
|
-
if match = fname.match(/application\.(js|css)$/)
|
83
|
-
sha1 = Digest::SHA1.hexdigest(open(fname).read)
|
84
|
-
html_options.merge! match[1] => sha1
|
85
|
-
static << (new_name = "application-#{sha1}.#{match[1]}")
|
86
|
-
FileUtils.cp_r fname, new_name
|
87
|
-
spawn "cat #{new_name} | gzip -9 > #{new_name}.gz"
|
88
|
-
else
|
89
|
-
FileUtils.cp_r fname, Pathname.new(fname).basename.to_s
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
service_presenters.each do |service_presenter|
|
94
|
-
create_file("index.html", service_presenter.to_html, force: true)
|
95
|
-
|
96
|
-
service_presenter.endpoints.each do |endpoint_prefix_group|
|
97
|
-
endpoint_prefix_group.each do |endpoint_presenter|
|
98
|
-
create_file(endpoint_presenter.relative_path, endpoint_presenter.to_html, force: true)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
89
|
+
create_file 'index.html', service_presenter.to_html, force: true
|
102
90
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
107
|
-
Dir.glob("*.css").each do |fname|
|
108
|
-
FileUtils.rm fname unless static.include? fname
|
109
|
-
end
|
110
|
-
Dir.glob("*.gz").each do |fname|
|
111
|
-
FileUtils.rm fname unless static.include? fname.sub(/\.gz/, '')
|
91
|
+
service_presenter.endpoints.each do |endpoint_prefix_group|
|
92
|
+
endpoint_prefix_group.each do |endpoint_presenter|
|
93
|
+
create_file(endpoint_presenter.relative_path, endpoint_presenter.to_html, force: true)
|
112
94
|
end
|
113
95
|
end
|
114
96
|
end
|
115
97
|
|
116
|
-
def
|
117
|
-
|
98
|
+
def setup_schema_root!(path)
|
99
|
+
Lurker.service_path = File.expand_path(path)
|
100
|
+
raise Lurker::NotFound.new(Lurker.service_path) unless Lurker.valid_service_path?
|
101
|
+
say_status :using, path
|
118
102
|
end
|
119
103
|
|
120
|
-
def
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
"public"
|
125
|
-
else
|
126
|
-
raise "Please, run it from `Rails.root` or pass `-o` option"
|
127
|
-
end
|
104
|
+
def setup_rendering_engine!
|
105
|
+
I18n.config.enforce_available_locales = true
|
106
|
+
Lurker::RenderingController.prepend_view_path templates_root
|
107
|
+
Lurker::RenderingController.config.assets_dir = assets_root
|
128
108
|
end
|
129
109
|
|
130
|
-
def
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
else
|
135
|
-
File.expand_path("../templates", origin_path)
|
136
|
-
end
|
110
|
+
def prepare_assets!
|
111
|
+
directory assets_root, '.', exclude_pattern: /application\.(js|css)$/
|
112
|
+
digest_asset!('application.js')
|
113
|
+
digest_asset!('application.css')
|
137
114
|
end
|
138
115
|
|
139
|
-
def
|
140
|
-
|
116
|
+
def cleanup_assets!
|
117
|
+
actual = assets.values
|
118
|
+
Dir.glob('*.{js,css,gz}').each do |fname|
|
119
|
+
remove_file fname unless actual.include? fname.sub(/\.gz/, '')
|
120
|
+
end
|
141
121
|
end
|
142
122
|
|
143
|
-
def
|
144
|
-
|
145
|
-
|
123
|
+
def digest_asset!(name)
|
124
|
+
if (asset_path = assets_root + name).exist?
|
125
|
+
digest_path = asset_digest_path(asset_path).basename
|
126
|
+
assets[asset_path.basename.to_s] = digest_path.to_s
|
127
|
+
copy_file asset_path, digest_path, skip: true
|
128
|
+
spawn "cat #{digest_path} | gzip -9 > #{digest_path}.gz"
|
146
129
|
end
|
147
130
|
end
|
148
131
|
|
132
|
+
def service_presenter
|
133
|
+
@service_presenter ||= Lurker::ServicePresenter.new(Lurker.service, html_options, &filtering_block)
|
134
|
+
end
|
135
|
+
|
149
136
|
def filtering_block
|
150
137
|
if options['select'].present?
|
151
138
|
select = /#{options['select']}/
|
@@ -167,29 +154,80 @@ module Lurker
|
|
167
154
|
|
168
155
|
def html_options
|
169
156
|
@html_options ||= {
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
157
|
+
static_html: true,
|
158
|
+
url_base_path: url_base_path.prepend('/'),
|
159
|
+
template_directory: templates_root,
|
160
|
+
assets_directory: assets_root,
|
161
|
+
assets: assets,
|
162
|
+
html_directory: output_path,
|
163
|
+
footer: footer,
|
164
|
+
lurker: gem_info
|
177
165
|
}
|
178
166
|
end
|
179
167
|
end
|
180
168
|
|
181
169
|
private
|
182
170
|
|
171
|
+
def output_path
|
172
|
+
"#{output_prefix}/#{url_base_path}"
|
173
|
+
end
|
174
|
+
|
175
|
+
def output_prefix
|
176
|
+
if explicit = options[:output]
|
177
|
+
explicit.sub(/\/?#{url_base_path}\/?$/, '')
|
178
|
+
elsif File.exists? 'public'
|
179
|
+
'public'
|
180
|
+
else
|
181
|
+
raise 'Please, run it from `Rails.root` or pass `-o` option'
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
183
185
|
def url_base_path
|
184
186
|
options[:url_base_path].presence.try(:strip).try(:sub, /^\/+/, '') || Lurker::DEFAULT_URL_BASE
|
185
187
|
end
|
186
188
|
|
189
|
+
def assets
|
190
|
+
@assets ||= {}
|
191
|
+
end
|
192
|
+
|
193
|
+
def assets_root
|
194
|
+
Lurker::Cli.assets_root
|
195
|
+
end
|
196
|
+
|
197
|
+
def templates_root
|
198
|
+
Lurker::Cli.templates_root
|
199
|
+
end
|
200
|
+
|
201
|
+
def asset_logical_path(path)
|
202
|
+
path = Pathname.new(path) unless path.is_a? Pathname
|
203
|
+
path.sub %r{-[0-9a-f]{40}\.}, '.'
|
204
|
+
end
|
205
|
+
|
206
|
+
def asset_digest_path(path)
|
207
|
+
path = Pathname.new(path) unless path.is_a? Pathname
|
208
|
+
asset_logical_path(path).sub(/\.(\w+)$/) { |ext| "-#{hexdigest(path)}#{ext}" }
|
209
|
+
end
|
210
|
+
|
211
|
+
def hexdigest(path)
|
212
|
+
Digest::SHA1.hexdigest(open(path).read)
|
213
|
+
end
|
214
|
+
|
215
|
+
def path_extnames(path)
|
216
|
+
File.basename(path).scan(/\.[^.]+/)
|
217
|
+
end
|
218
|
+
|
219
|
+
def footer
|
220
|
+
`git rev-parse --short HEAD`.to_s.strip
|
221
|
+
rescue
|
222
|
+
''
|
223
|
+
end
|
224
|
+
|
187
225
|
def gem_info
|
188
226
|
spec = if Bundler.respond_to? :locked_gems
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
227
|
+
Bundler.locked_gems.specs.select { |s| s.name == 'lurker' }.first # 1.6
|
228
|
+
else
|
229
|
+
Bundler.definition.sources.detect { |s| s.specs.map(&:name).include?('lurker') } # 1.3
|
230
|
+
end
|
193
231
|
|
194
232
|
if spec.source.respond_to? :revision, true # bundler 1.3 private
|
195
233
|
"#{spec.name} (#{spec.source.send(:revision)})"
|
@@ -198,26 +236,7 @@ module Lurker
|
|
198
236
|
end
|
199
237
|
rescue => e
|
200
238
|
puts e
|
201
|
-
|
202
|
-
end
|
203
|
-
|
204
|
-
def get_content(content_fname)
|
205
|
-
return unless content_fname
|
206
|
-
content_fname = File.expand_path(content_fname)
|
207
|
-
if content_fname.ends_with? 'md'
|
208
|
-
Lurker.safe_require('kramdown')
|
209
|
-
Kramdown::Document.new(open(content_fname).read).to_html
|
210
|
-
else
|
211
|
-
''
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
def services
|
216
|
-
@services ||= [Lurker::Service.new(origin_path)]
|
217
|
-
end
|
218
|
-
|
219
|
-
def origin
|
220
|
-
Pathname.new(origin_path)
|
239
|
+
'lurker (unknown)'
|
221
240
|
end
|
222
241
|
end
|
223
242
|
end
|
data/lib/lurker/endpoint.rb
CHANGED
@@ -19,7 +19,7 @@ module Lurker
|
|
19
19
|
RESPONSE_CODES = 'responseCodes'.freeze
|
20
20
|
REQUEST_PARAMETERS = 'requestParameters'.freeze
|
21
21
|
RESPONSE_PARAMETERS = 'responseParameters'.freeze
|
22
|
-
|
22
|
+
DESCRIPTIONS = {
|
23
23
|
'index' => 'listing',
|
24
24
|
'show' => '',
|
25
25
|
'edit' => 'editing',
|
@@ -44,7 +44,7 @@ module Lurker
|
|
44
44
|
finalize_schema!
|
45
45
|
|
46
46
|
Lurker::Json::Orderer.reorder(schema) unless persisted?
|
47
|
-
Lurker::Json::
|
47
|
+
Lurker::Json::Writer.write(schema, endpoint_path)
|
48
48
|
|
49
49
|
@persisted = true
|
50
50
|
end
|
@@ -131,6 +131,10 @@ module Lurker
|
|
131
131
|
@schema[RESPONSE_CODES]
|
132
132
|
end
|
133
133
|
|
134
|
+
def documentation
|
135
|
+
@schema.documentation
|
136
|
+
end
|
137
|
+
|
134
138
|
protected
|
135
139
|
|
136
140
|
def persisted?
|
@@ -167,7 +171,7 @@ module Lurker
|
|
167
171
|
def finalize_schema!
|
168
172
|
path_params = schema[EXTENSIONS][PATH_PARAMS] || {}
|
169
173
|
subject = path_params[CONTROLLER].to_s.split(/\//).last.to_s
|
170
|
-
description =
|
174
|
+
description = DESCRIPTIONS[path_params[ACTION]]
|
171
175
|
|
172
176
|
schema[DESCRIPTION] = "#{subject.singularize} #{description}".strip if schema[DESCRIPTION].blank?
|
173
177
|
schema[PREFIX] = "#{subject} management" if schema[PREFIX].blank?
|