spectacle 0.1.2 → 0.1.3

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 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