spectacle 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b42ae059b23d5ff986e540814af430c8caaa0626
4
- data.tar.gz: aa149c1772cdfe1d28e949a1d2db6e660e77450c
3
+ metadata.gz: d8645f5fab30045d8686a7f8b69f0a1f7a4eab05
4
+ data.tar.gz: 478971030bbed4d15d6ec750b9d30c4fd61be65f
5
5
  SHA512:
6
- metadata.gz: 36053c1424daf39030a9ada1ebb67615153c5bc998f762119dd0719ba1e95a91f8ec5fda7d230d07a8c72029807a6311415c74b33e451f0d56961876f4bc7267
7
- data.tar.gz: 08a660ac60c8932c97bdce2566e573b773f7f94a62481f3eeed7a78396ace18404b210a58b1a6eb84b356bf865ebe0a942231ba7d702c6923e3bf541a5f1ab18
6
+ metadata.gz: 7ad38f4006eb10b8a169d6596c1cb2c040e9b6ca29c55332e34bef41f201d4ad4bb1d4443e6305aeb062cbf69cb74dbf72f7694afb33bd6c509b4e990652dce5
7
+ data.tar.gz: eefa8e706a0aaa847642fdbd913efd0299f7cc9d46ccdd1b8e1e953a779d3af8a04b2e51e4691c77a37f96ad1855e9308d69f8b17a0bd9419ee640993a132b98
data/.gitignore CHANGED
@@ -20,3 +20,4 @@ bak
20
20
  node_modules
21
21
  app/views/*/*
22
22
  vendor/assets/*/*
23
+ !vendor/assets/stylesheets/spectacle-core.scss
@@ -1,3 +1,3 @@
1
1
  Spectacle::Engine.routes.draw do
2
- root 'apidocs#show'
2
+ # root 'apidocs#show'
3
3
  end
@@ -1,5 +1,5 @@
1
1
  require "spectacle/config"
2
- require "spectacle/engine"
3
2
  require "spectacle/dsl"
4
3
  require "spectacle/task"
5
4
  require "spectacle/version"
5
+ # require "spectacle/engine"
@@ -1,79 +1,60 @@
1
1
  module Spectacle
2
2
  class Config
3
3
  class << self
4
-
5
- def target_dir= value
6
- @versions = value
4
+ attr_writer :spec_file
5
+ def spec_file
6
+ @spec_file || File.join(Rails.root, 'public/swagger.json')
7
7
  end
8
8
 
9
+ attr_writer :target_dir
9
10
  def target_dir
10
- @target_dir ||= 'public/apidocs'
11
+ @target_dir || File.join(Rails.root, 'public/v1/docs')
11
12
  end
12
13
 
13
- def spec_file= value
14
- @spec_file = value
14
+ attr_writer :logo_file
15
+ def logo_file
16
+ @logo_file || nil
15
17
  end
16
18
 
17
- def spec_file
18
- @spec_file ||= 'public/swagger.json'
19
+ attr_writer :embedded_mode
20
+ def embedded_mode
21
+ @embedded_mode || false
19
22
  end
20
23
 
24
+ # Get the Spectacle library directory
25
+ #
26
+ # @return path
27
+ #
28
+ attr_writer :spectacle_lib_dir
29
+ def spectacle_lib_dir
30
+ return @spectacle_lib_dir if @spectacle_lib_dir
31
+ if Gem.win_platform?
32
+ File.join(node_prefix, 'node_modules', 'spectacle-docs')
33
+ else
34
+ File.join(node_prefix, 'lib', 'node_modules', 'spectacle-docs')
35
+ end
36
+ end
21
37
 
22
- # @@base_api_controller = nil
23
- #
24
- # def base_api_controller
25
- # @@base_api_controller || ActionController::Base
26
- # end
27
- #
28
- # def base_api_controllers
29
- # Array(base_api_controller)
30
- # end
31
- #
32
- # def base_api_controller=(controller)
33
- # @@base_api_controller = controller
34
- # end
35
- #
36
- # alias_method :base_api_controllers=, :base_api_controller=
37
- #
38
- # def base_applications
39
- # Array(base_application)
40
- # end
41
- #
42
- # def base_application
43
- # Rails.application
44
- # end
45
- #
46
- # def register_apis(versions)
47
- # base_api_controllers.each do |controller|
48
- # controller.send(:include, ImpotentMethods)
38
+ # # Get the Spectacle bin directory
39
+ # #
40
+ # # @return path
41
+ # #
42
+ # def spectacle_bin_path
43
+ # return @spectacle_bin_path if @spectacle_bin_path
44
+ # if Gem.win_platform?
45
+ # File.join(node_prefix, 'bin', 'spectacle')
46
+ # else
47
+ # File.join(node_prefix, 'spectacle')
49
48
  # end
50
- # @versions = versions
51
- # end
52
- #
53
- # def registered_apis
54
- # @versions ||= {}
55
- # end
56
- #
57
- # def transform_path(path, api_version)
58
- # # This is only for overriding, so don't perform any path transformations by default.
59
- # path
60
- # end
61
- #
62
- # def log_exception
63
- # yield
64
- # rescue => e
65
- # write_log(:error, e)
66
- # raise
67
49
  # end
50
+
51
+ # Get the Node.js install prefix
68
52
  #
69
- # def log_env_name
70
- # 'SD_LOG_LEVEL'
71
- # end
53
+ # @return path
72
54
  #
73
- # def write_log(type, output)
74
- # $stderr.puts output if type == :error and ENV[log_env_name]=="1"
75
- # end
76
-
55
+ def node_prefix
56
+ `npm config get prefix`.strip
57
+ end
77
58
  end
78
59
  end
79
60
  end
@@ -1,335 +1,139 @@
1
- require 'open3'
2
-
3
1
  module Spectacle
4
2
  class DSL
5
-
6
- DEFAULT_CONFIG = {
7
- spectacle_dir: 'node_modules/spectacle-docs' #,
8
- # target_dir: 'public/apidocs',
9
- # spec_path: 'public/swagger.json'#,
10
- # :base_path: '/',
11
- # :clean_directory: false,
12
- # :formatting: :pretty
13
- }
14
-
15
3
  class << self
16
4
 
17
- #
18
- # Generate Spectacle static documentation
5
+ # Install Spectacle using `npm`
19
6
  #
20
7
  # @return success
21
8
  #
22
- def generate
23
- res = run "-C -e #{Config.spec_file}"
24
- p res
25
- if res[2]
26
- source_dir = "#{DEFAULT_CONFIG[:spectacle_dir]}/app"
27
- build_dir = "#{DEFAULT_CONFIG[:spectacle_dir]}/public"
28
- views_dir = './app/views/spectacle'
29
- assets_dir = './vendor/assets'
30
-
31
- FileUtils.mkdir_p views_dir
32
- FileUtils.mkdir_p "#{assets_dir}/stylesheets"
33
- FileUtils.mkdir_p "#{assets_dir}/javascripts"
34
-
35
- FileUtils.cp "#{build_dir}/index.html",
36
- "#{views_dir}/_docs.html.erb"
37
- FileUtils.cp Dir.glob("#{source_dir}/stylesheets/*"),
38
- "#{assets_dir}/stylesheets"
39
- # FileUtils.copy "#{build_dir}/stylesheets/spectacle.css",
40
- # "#{assets_dir}/stylesheets/spectacle.css"
41
- FileUtils.cp "#{build_dir}/javascripts/spectacle.js",
42
- "#{assets_dir}/javascripts/spectacle.js"
43
- end
44
- res
9
+ def install
10
+ system 'npm install -g spectacle-docs'
45
11
  end
46
12
 
47
- #
48
- # Install Spectacle using `npm`
13
+ # Generate Spectacle documentation
49
14
  #
50
15
  # @return success
51
16
  #
52
- def install
53
- sh "npm install spectacle-docs"
17
+ def generate
18
+ spectacle arguments
54
19
  end
55
20
 
56
- #
57
21
  # Run the Spectacle shell command
58
22
  #
59
23
  # @param args the command line arguments to pass to spectacle
60
24
  #
61
25
  # @return success
62
26
  #
63
- def run args
64
- sh "cd #{DEFAULT_CONFIG[:spectacle_dir]} && node bin/cli #{args}"
27
+ def spectacle args
28
+ # system "spectacle #{args}"
29
+ system "cd #{Config.spectacle_lib_dir} && node bin/spectacle-cli #{args}"
65
30
  end
66
31
 
32
+ # Generate Spectacle command line arguments
67
33
  #
68
- # Identical to Open3.capture3, except that it rescues runtime errors
34
+ # @return string
69
35
  #
70
- # @param env optional (as `Kernel.system')
71
- # @param *cmd the command and its (auto-escaped) arguments
72
- # @param opts optional a hash of options (as `Kernel.system')
36
+ def arguments
37
+ s = '' #'-C '
38
+ s += '-e ' if Config.embedded_mode
39
+ s += "-l #{Config.logo_file} " if Config.logo_file
40
+ s += Config.spec_file
41
+ end
42
+
43
+ # Replace paths in generated static documentation HTML
73
44
  #
74
- # @return [stdout, stderr, success]
45
+ # @return success
75
46
  #
76
- def sh(*cmd)
77
- begin
78
- stdout, stderr, status = Open3.capture3(*cmd)
79
- [stdout, stderr, status.success?]
80
- rescue
81
- [$/, $/, nil]
47
+ def replace_static_asset_paths
48
+ if Config.target_dir.include?('/public/')
49
+ base_dir = Config.target_dir.match('/public(.*)')[1]
50
+ html_path = "#{Config.target_dir}/index.html"
51
+ contents = File.open(html_path, &:read)
52
+ contents.gsub!('/images', base_dir + '/images')
53
+ contents.gsub!('/stylesheets', base_dir + '/stylesheets')
54
+ contents.gsub!('/javascripts', base_dir + '/javascripts')
55
+ File.write(html_path, contents)
82
56
  end
83
57
  end
84
58
 
85
- # def set_real_methods
86
- # # replace impotent methods with live ones
87
- # Config.base_api_controllers.each do |controller|
88
- # controller.send(:include, Methods)
89
- # end
90
- # end
91
- #
92
- # def write_docs(apis = nil)
93
- # results = generate_docs(apis)
94
- # results.each{|api_version, result| write_doc(result) }
95
- # end
59
+ # Copy generated static documentation HTML into the public folder
96
60
  #
97
- # def write_doc(result)
98
- # settings = result[:settings]
99
- # config = result[:config]
100
- # create_output_paths(settings[:api_file_path])
101
- # clean_output_paths(settings[:api_file_path]) if config[:clean_directory] || false
102
- # root = result[:root]
103
- # resources = root.delete 'resources'
104
- # root.merge!(config[:attributes] || {}) # merge custom user attributes like info
105
- # # write the api-docs file
106
- # write_to_file('#{settings[:api_file_path]}/#{config[:api_file_name]}', root, config)
107
- # # write the individual resource files
108
- # resources.each do |resource|
109
- # resource_file_path = resource.delete 'resourceFilePath'
110
- # write_to_file(File.join(settings[:api_file_path], '#{resource_file_path}.json'), resource, config)
111
- # end
112
- # result
113
- # end
114
- #
115
- # def generate_docs(apis=nil)
116
- # apis ||= Config.registered_apis
117
- # results = {}
118
- # set_real_methods
119
- #
120
- # apis[DEFAULT_VER] = DEFAULT_CONFIG if apis.empty?
121
- #
122
- # apis.each do |api_version, config|
123
- # settings = get_settings(api_version, config)
124
- # config.reverse_merge!(DEFAULT_CONFIG)
125
- # results[api_version] = generate_doc(api_version, settings, config)
126
- # results[api_version][:settings] = settings
127
- # results[api_version][:config] = config
128
- # end
129
- # results
130
- # end
131
- #
132
- # def generate_doc(api_version, settings, config)
133
- # root = {
134
- # 'apiVersion': api_version,
135
- # 'swaggerVersion': '1.2',
136
- # 'basePath': settings[:base_path],
137
- # :apis: [],
138
- # :authorizations: settings[:authorizations]
139
- # }
140
- # results = {:processed: [], :skipped: []}
141
- # resources = []
142
- #
143
- # get_route_paths(settings[:controller_base_path]).each do |path|
144
- # ret = process_path(path, root, config, settings)
145
- # results[ret[:action]] << ret
146
- # if ret[:action] == :processed
147
- # resources << generate_resource(ret[:path], ret[:apis], ret[:models], settings, root, config, ret[:klass].swagger_config)
148
- # debased_path = get_debased_path(ret[:path], settings[:controller_base_path])
149
- # resource_api = {
150
- # path: '/#{Config.transform_path(trim_leading_slash(debased_path), api_version)}.{format}',
151
- # description: ret[:klass].swagger_config[:description]
152
- # }
153
- # root[:apis] << resource_api
154
- # end
155
- # end
156
- # root['resources'] = resources
157
- # results[:root] = root
158
- # results
159
- # end
160
- #
161
- # private
162
- #
163
- # def transform_spec_to_api_path(spec, controller_base_path, extension)
164
- # api_path = spec.to_s.dup
165
- # api_path.gsub!('(.:format)', extension ? '.#{extension}' : '')
166
- # api_path.gsub!(/:(\w+)/, '{\1}')
167
- # api_path.gsub!(controller_base_path, '')
168
- # '/' + trim_slashes(api_path)
169
- # end
170
- #
171
- # def camelize_keys_deep!(h)
172
- # h.keys.each do |k|
173
- # ks = k.to_s.camelize(:lower)
174
- # h[ks] = h.delete k
175
- # camelize_keys_deep! h[ks] if h[ks].kind_of? Hash
176
- # if h[ks].kind_of? Array
177
- # h[ks].each do |a|
178
- # next unless a.kind_of? Hash
179
- # camelize_keys_deep! a
180
- # end
181
- # end
182
- # end
183
- # end
184
- #
185
- # def trim_leading_slash(str)
186
- # return str if !str
187
- # str.gsub(/\A\/+/, '')
188
- # end
189
- #
190
- # def trim_trailing_slash(str)
191
- # return str if !str
192
- # str.gsub(/\/+\z/, '')
193
- # end
194
- #
195
- # def trim_slashes(str)
196
- # trim_leading_slash(trim_trailing_slash(str))
197
- # end
198
- #
199
- # def get_debased_path(path, controller_base_path)
200
- # path.gsub('#{controller_base_path}', '')
201
- # end
202
- #
203
- # def process_path(path, root, config, settings)
204
- # return {action: :skipped, reason: :empty_path} if path.empty?
205
- # klass = Config.log_exception { '#{path.to_s.camelize}Controller'.constantize } rescue nil
206
- # return {action: :skipped, path: path, reason: :klass_not_present} if !klass
207
- # return {action: :skipped, path: path, reason: :not_swagger_resource} if !klass.methods.include?(:swagger_config) or !klass.swagger_config[:controller]
208
- # return {action: :skipped, path: path, reason: :not_kind_of_parent_controller} if config[:parent_controller] && !(klass < config[:parent_controller])
209
- # apis, models, defined_nicknames = [], {}, []
210
- # routes.select{|i| i.defaults[:controller] == path}.each do |route|
211
- # unless nickname_defined?(defined_nicknames, path, route) # only add once for each route once e.g. PATCH, PUT
212
- # ret = get_route_path_apis(path, route, klass, settings, config)
213
- # apis = apis + ret[:apis]
214
- # models.merge!(ret[:models])
215
- # defined_nicknames << ret[:nickname] if ret[:nickname].present?
216
- # end
217
- # end
218
- # {action: :processed, path: path, apis: apis, models: models, klass: klass}
219
- # end
220
- #
221
- # def route_verbs(route)
222
- # if defined?(route.verb.source) then route.verb.source.to_s.delete('$'+'^').split('|') else [route.verb] end.collect{|verb| verb.downcase.to_sym}
223
- # end
224
- #
225
- # def path_route_nickname(path, route)
226
- # action = route.defaults[:action]
227
- # '#{path.camelize}##{action}'
228
- # end
229
- #
230
- # def nickname_defined?(defined_nicknames, path, route)
231
- # target_nickname = path_route_nickname(path, route)
232
- # defined_nicknames.each{|nickname| return true if nickname == target_nickname }
233
- # false
234
- # end
235
- #
236
- # def generate_resource(path, apis, models, settings, root, config, swagger_config)
237
- # metadata = ApiDeclarationFileMetadata.new(
238
- # root['apiVersion'], path, root['basePath'],
239
- # settings[:controller_base_path],
240
- # camelize_model_properties: config.fetch(:camelize_model_properties, true),
241
- # swagger_version: root['swaggerVersion'],
242
- # authorizations: root[:authorizations],
243
- # resource_path: swagger_config[:resource_path]
244
- # )
245
- # declaration = ApiDeclarationFile.new(metadata, apis, models)
246
- # declaration.generate_resource
247
- # end
248
- #
249
- # def routes
250
- # Config.base_applications.map{|app| app.routes.routes.to_a }.flatten
251
- # end
252
- #
253
- # def get_route_path_apis(path, route, klass, settings, config)
254
- # models, apis = {}, []
255
- # action = route.defaults[:action]
256
- # verbs = route_verbs(route)
257
- # return {apis: apis, models: models, nickname: nil} if !operation = klass.swagger_actions[action.to_sym]
258
- # operation = Hash[operation.map {|k, v| [k.to_s.gsub('@','').to_sym, v.respond_to?(:deep_dup) ? v.deep_dup : v.dup] }] # rename :@instance hash keys
259
- # nickname = operation[:nickname] = path_route_nickname(path, route)
260
- #
261
- # route_path = if defined?(route.path.spec) then route.path.spec else route.path end
262
- # api_path = transform_spec_to_api_path(route_path, settings[:controller_base_path], config[:api_extension_type])
263
- # operation[:parameters] = filter_path_params(api_path, operation[:parameters]) if operation[:parameters]
264
- # operations = verbs.collect{|verb|
265
- # op = operation.dup
266
- # op[:method] = verb
267
- # op
268
- # }
269
- # apis << {:path: api_path, :operations: operations}
270
- # models = get_klass_models(klass)
271
- #
272
- # {apis: apis, models: models, nickname: nickname}
273
- # end
274
- #
275
- # def get_klass_models(klass)
276
- # models = {}
277
- # # Add any declared models to the root of the resource.
278
- # klass.swagger_models.each do |model_name, model|
279
- # formatted_model = {
280
- # id: model[:id],
281
- # required: model[:required],
282
- # properties: model[:properties],
283
- # }
284
- # formatted_model[:description] = model[:description] if model[:description]
285
- # models[model[:id]] = formatted_model
286
- # end
287
- # models
288
- # end
289
- #
290
- # def get_settings(api_version, config)
291
- # base_path = trim_trailing_slash(config[:base_path] || '')
292
- # controller_base_path = trim_leading_slash(config[:controller_base_path] || '')
293
- # base_path += '/#{controller_base_path}' unless controller_base_path.empty?
294
- # api_file_path = config[:api_file_path]
295
- # authorizations = config[:authorizations]
296
- # settings = {
297
- # base_path: base_path,
298
- # controller_base_path: controller_base_path,
299
- # api_file_path: api_file_path,
300
- # authorizations: authorizations
301
- # }.freeze
302
- # end
303
- #
304
- # def get_route_paths(controller_base_path)
305
- # paths = routes.map{|i| '#{i.defaults[:controller]}' }
306
- # paths.uniq.select{|i| i.start_with?(controller_base_path)}
307
- # end
308
- #
309
- # def create_output_paths(api_file_path)
310
- # FileUtils.mkdir_p(api_file_path) # recursively create out output path
311
- # end
312
- #
313
- # def clean_output_paths(api_file_path)
314
- # Dir.foreach(api_file_path) do |f|
315
- # fn = File.join(api_file_path, f)
316
- # File.delete(fn) if !File.directory?(fn) and File.extname(fn) == '.json'
317
- # end
318
- # end
61
+ # @return success
319
62
  #
320
- # def write_to_file(path, structure, config={})
321
- # content = case config[:formatting]
322
- # when :pretty; JSON.pretty_generate structure
323
- # else; structure.to_json
324
- # end
325
- # FileUtils.mkdir_p File.dirname(path)
326
- # File.open(path, 'w') { |file| file.write content }
63
+ def copy_static
64
+ build_dir = "#{Config.spectacle_lib_dir}/public"
65
+
66
+ # Prepare the target folder
67
+ FileUtils.rm_rf Config.target_dir if File.exist?(Config.target_dir)
68
+ FileUtils.mkdir_p Config.target_dir
69
+
70
+ # Copy the SCSS files from the spectacle source tree to the
71
+ # assets folder
72
+ puts "Copying HTML from #{build_dir}/* to #{Config.target_dir}"
73
+ FileUtils.copy_entry build_dir, Config.target_dir
74
+
75
+ replace_static_asset_paths
76
+ end
77
+
78
+ # # Copy generated documentation HTML into the asset pipeline for dynamic
79
+ # # inclusion.
80
+ # #
81
+ # # @return success
82
+ # #
83
+ # def copy_dynamic
84
+ # source_dir = "#{Config.spectacle_lib_dir}/app"
85
+ # build_dir = "#{Config.spectacle_lib_dir}/public"
86
+ #
87
+ # gem_dir = File.expand_path File.join(File.dirname(__FILE__), '../../')
88
+ # views_dir = "#{gem_dir}/app/views/spectacle"
89
+ # assets_dir = "#{gem_dir}/vendor/assets"
90
+ #
91
+ # # Prepare the assets pipeline
92
+ # FileUtils.mkdir_p views_dir
93
+ # FileUtils.mkdir_p "#{assets_dir}/stylesheets"
94
+ # FileUtils.mkdir_p "#{assets_dir}/javascripts"
95
+ #
96
+ # # Copy compiled HTML to the views folder as a ERB partial.
97
+ # # This way it can be included in any page.
98
+ # puts "Copying HTML from #{build_dir}/index.html to #{views_dir}/_docs.html.erb"
99
+ # FileUtils.cp "#{build_dir}/index.html",
100
+ # "#{views_dir}/_docs.html.erb"
101
+ #
102
+ # # Copy the SCSS files from the spectacle source tree to the
103
+ # # assets folder
104
+ # puts "Copying SCSS from #{source_dir}/stylesheets/* to #{assets_dir}/stylesheets"
105
+ # FileUtils.cp Dir.glob("#{source_dir}/stylesheets/*"),
106
+ # "#{assets_dir}/stylesheets"
107
+ #
108
+ # # Copy the compiled CSS files. These can be used optionally instead
109
+ # # of SCSS files if no configuration is required.
110
+ # # FileUtils.cp "#{build_dir}/stylesheets/spectacle.css",
111
+ # # "#{assets_dir}/stylesheets/spectacle.css"
112
+ # # FileUtils.cp "#{build_dir}/stylesheets/foundation.css",
113
+ # # "#{assets_dir}/stylesheets/foundation.css"
114
+ #
115
+ # # Copy the compiled JS files to the assets folder
116
+ # puts "Copying JS from #{build_dir}/javascripts/spectacle.js to #{assets_dir}/javascripts/spectacle.js"
117
+ # FileUtils.cp "#{build_dir}/javascripts/spectacle.js",
118
+ # "#{assets_dir}/javascripts/spectacle.js"
119
+ #
120
+ # replace_static_asset_paths
327
121
  # end
328
- #
329
- # def filter_path_params(path, params)
330
- # params.reject do |param|
331
- # param_as_variable = '{#{param[:name]}}'
332
- # param[:param_type] == :path && !path.include?(param_as_variable)
122
+
123
+ # # Identical to Open3.capture3, except that it rescues runtime errors
124
+ # #
125
+ # # @param env optional (as `Kernel.system')
126
+ # # @param *cmd the command and its (auto-escaped) arguments
127
+ # # @param opts optional a hash of options (as `Kernel.system')
128
+ # #
129
+ # # @return [stdout, stderr, success]
130
+ # #
131
+ # def sh *cmd
132
+ # begin
133
+ # stdout, stderr, status = Open3.capture3(*cmd)
134
+ # [stdout, stderr, status.success?]
135
+ # rescue
136
+ # [$/, $/, false]
333
137
  # end
334
138
  # end
335
139
  end