jazzy 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +27 -0
  3. data/.travis.yml +2 -2
  4. data/CHANGELOG.md +41 -0
  5. data/Gemfile.lock +10 -12
  6. data/README.md +80 -14
  7. data/Rakefile +1 -3
  8. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/SourceKittenFramework +0 -0
  9. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Commandant +0 -0
  10. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Versions/A/Commandant +0 -0
  11. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Versions/A/Resources/Info.plist +5 -5
  12. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Result +0 -0
  13. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Versions/A/Resources/Info.plist +4 -4
  14. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Versions/A/Result +0 -0
  15. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/SWXMLHash +0 -0
  16. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/Versions/A/Resources/Info.plist +4 -4
  17. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/Versions/A/SWXMLHash +0 -0
  18. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SwiftXPC.framework/SwiftXPC +0 -0
  19. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SwiftXPC.framework/Versions/A/Resources/Info.plist +5 -5
  20. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SwiftXPC.framework/Versions/A/SwiftXPC +0 -0
  21. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/libswiftCore.dylib +0 -0
  22. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/libswiftCoreGraphics.dylib +0 -0
  23. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/libswiftDarwin.dylib +0 -0
  24. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/libswiftDispatch.dylib +0 -0
  25. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/libswiftFoundation.dylib +0 -0
  26. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/libswiftObjectiveC.dylib +0 -0
  27. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Resources/Info.plist +5 -5
  28. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/SourceKittenFramework +0 -0
  29. data/lib/jazzy/SourceKitten/bin/sourcekitten +0 -0
  30. data/lib/jazzy/assets/css/jazzy.css.scss +39 -14
  31. data/lib/jazzy/config.rb +342 -182
  32. data/lib/jazzy/doc.rb +8 -19
  33. data/lib/jazzy/doc_builder.rb +38 -26
  34. data/lib/jazzy/docset_builder.rb +4 -3
  35. data/lib/jazzy/executable.rb +2 -1
  36. data/lib/jazzy/gem_version.rb +1 -1
  37. data/lib/jazzy/jazzy_markdown.rb +16 -4
  38. data/lib/jazzy/podspec_documenter.rb +25 -11
  39. data/lib/jazzy/readme_generator.rb +7 -7
  40. data/lib/jazzy/source_declaration.rb +2 -0
  41. data/lib/jazzy/source_declaration/access_control_level.rb +21 -15
  42. data/lib/jazzy/source_declaration/type.rb +79 -5
  43. data/lib/jazzy/sourcekitten.rb +150 -24
  44. data/lib/jazzy/templates/doc.mustache +2 -2
  45. data/lib/jazzy/templates/nav.mustache +1 -1
  46. data/lib/jazzy/templates/task.mustache +26 -10
  47. data/spec/integration_spec.rb +34 -39
  48. metadata +2 -2
@@ -3,7 +3,7 @@
3
3
  <plist version="1.0">
4
4
  <dict>
5
5
  <key>BuildMachineOSBuild</key>
6
- <string>15B30a</string>
6
+ <string>15B42</string>
7
7
  <key>CFBundleDevelopmentRegion</key>
8
8
  <string>en</string>
9
9
  <key>CFBundleExecutable</key>
@@ -17,7 +17,7 @@
17
17
  <key>CFBundlePackageType</key>
18
18
  <string>FMWK</string>
19
19
  <key>CFBundleShortVersionString</key>
20
- <string>0.5.1</string>
20
+ <string>0.6.0</string>
21
21
  <key>CFBundleSignature</key>
22
22
  <string>????</string>
23
23
  <key>CFBundleSupportedPlatforms</key>
@@ -29,7 +29,7 @@
29
29
  <key>DTCompiler</key>
30
30
  <string>com.apple.compilers.llvm.clang.1_0</string>
31
31
  <key>DTPlatformBuild</key>
32
- <string>7A1001</string>
32
+ <string>7B91b</string>
33
33
  <key>DTPlatformVersion</key>
34
34
  <string>GM</string>
35
35
  <key>DTSDKBuild</key>
@@ -37,9 +37,9 @@
37
37
  <key>DTSDKName</key>
38
38
  <string>macosx10.11</string>
39
39
  <key>DTXcode</key>
40
- <string>0701</string>
40
+ <string>0710</string>
41
41
  <key>DTXcodeBuild</key>
42
- <string>7A1001</string>
42
+ <string>7B91b</string>
43
43
  <key>NSHumanReadableCopyright</key>
44
44
  <string>Copyright © 2015 SourceKitten. All rights reserved.</string>
45
45
  </dict>
@@ -11,7 +11,7 @@ $white_color: #fff;
11
11
  $light_gray_bg_color: #f2f2f2;
12
12
  $declaration_bg_color: #f9f9f9;
13
13
  $sidebar_bg_color: #f9f9f9;
14
- $declaration_lang_title_swift_color: #4b8afb;
14
+ $declaration_title_language_color: #4b8afb;
15
15
 
16
16
  $sidebar_width: 230px;
17
17
  $content_wrapper_width: 980px;
@@ -24,7 +24,12 @@ $breadcrumb_padding_top: 17px;
24
24
  $code_font: 0.95em Menlo, monospace;
25
25
 
26
26
  $gray_border: 1px solid #e2e2e2;
27
- $declaration_swift_border: 5px solid #cde9f4;
27
+ $declaration_language_border: 5px solid #cde9f4;
28
+
29
+ $aside_color: #aaa;
30
+ $aside_border: 5px solid lighten($aside_color, 20%);
31
+ $aside_warning_color: #ff0000;
32
+ $aside_warning_border: 5px solid lighten($aside_warning_color, 20%);
28
33
 
29
34
  ////////////////////////////////
30
35
  // Reset
@@ -264,13 +269,6 @@ header {
264
269
  overflow-x: auto;
265
270
  }
266
271
 
267
- .aside-title {
268
- font-size: 9px;
269
- letter-spacing: 2px;
270
- text-transform: uppercase;
271
- padding-bottom: 0;
272
- }
273
-
274
272
  .declaration .highlight {
275
273
  overflow-x: initial; // This allows the scrollbar to show up inside declarations
276
274
  padding: 0 40px 40px 0;
@@ -313,6 +311,11 @@ header {
313
311
  padding-left: 3px;
314
312
  margin-left: 15px;
315
313
  }
314
+ .declaration-note {
315
+ font-size: .85em;
316
+ color: rgba(128,128,128,1);
317
+ font-style: italic;
318
+ }
316
319
  }
317
320
 
318
321
  .pointer-container {
@@ -356,15 +359,37 @@ header {
356
359
  }
357
360
  }
358
361
 
359
- div.Swift {
360
- padding: 4px 0 2px 10px;
361
- margin-bottom: 1em;
362
- border-left: $declaration_swift_border;
362
+ .aside, .language {
363
+ padding: 6px 12px;
364
+ margin: 12px 0;
365
+ border-left: $aside_border;
363
366
  overflow-y: hidden;
364
367
  .aside-title {
365
- color: $declaration_lang_title_swift_color;
368
+ font-size: 9px;
369
+ letter-spacing: 2px;
370
+ text-transform: uppercase;
371
+ padding-bottom: 0;
372
+ margin: 0;
373
+ color: $aside_color;
366
374
  -webkit-user-select: none;
367
375
  }
376
+ p:last-child {
377
+ margin-bottom: 0;
378
+ }
379
+ }
380
+
381
+ .language {
382
+ border-left: $declaration_language_border;
383
+ .aside-title {
384
+ color: $declaration_title_language_color;
385
+ }
386
+ }
387
+
388
+ .aside-warning {
389
+ border-left: $aside_warning_border;
390
+ .aside-title {
391
+ color: $aside_warning_color;
392
+ }
368
393
  }
369
394
 
370
395
  .graybox {
@@ -9,57 +9,248 @@ require 'jazzy/source_declaration/access_control_level'
9
9
  module Jazzy
10
10
  # rubocop:disable Metrics/ClassLength
11
11
  class Config
12
- attr_accessor :output
13
- attr_accessor :xcodebuild_arguments
14
- attr_accessor :author_name
15
- attr_accessor :module_name
16
- attr_accessor :github_url
17
- attr_accessor :github_file_prefix
18
- attr_accessor :author_url
19
- attr_accessor :dash_url
20
- attr_accessor :sourcekitten_sourcefile
21
- attr_accessor :clean
22
- attr_accessor :readme_path
23
- attr_accessor :docset_platform
24
- attr_accessor :root_url
25
- attr_accessor :version
26
- attr_accessor :min_acl
27
- attr_accessor :skip_undocumented
28
- attr_accessor :hide_documentation_coverage
29
- attr_accessor :podspec
30
- attr_accessor :docset_icon
31
- attr_accessor :docset_path
32
- attr_accessor :source_directory
33
- attr_accessor :excluded_files
34
- attr_accessor :custom_categories
35
- attr_accessor :template_directory
36
- attr_accessor :swift_version
37
- attr_accessor :assets_directory
38
- attr_accessor :copyright
12
+ # rubocop:disable Style/AccessorMethodName
13
+ class Attribute
14
+ attr_reader :name, :description, :command_line, :default, :parse
15
+
16
+ def initialize(name, description: nil, command_line: nil,
17
+ default: nil, parse: ->(x) { x })
18
+ @name = name
19
+ @description = Array(description)
20
+ @command_line = Array(command_line)
21
+ @default = default
22
+ @parse = parse
23
+ end
39
24
 
40
- def initialize
41
- PodspecDocumenter.configure(self, Dir['*.podspec{,.json}'].first)
42
- self.output = Pathname('docs')
43
- self.xcodebuild_arguments = []
44
- self.author_name = ''
45
- self.module_name = ''
46
- self.author_url = URI('')
47
- self.clean = false
48
- self.docset_platform = 'jazzy'
49
- self.version = '1.0'
50
- self.min_acl = SourceDeclaration::AccessControlLevel.public
51
- self.skip_undocumented = false
52
- self.hide_documentation_coverage = false
53
- self.source_directory = Pathname.pwd
54
- self.excluded_files = []
55
- self.custom_categories = {}
56
- self.template_directory = Pathname(__FILE__).parent + 'templates'
57
- self.swift_version = '2.0'
58
- self.assets_directory = Pathname(__FILE__).parent + 'assets'
25
+ def get(config)
26
+ config.method(name).call
27
+ end
28
+
29
+ def set_raw(config, val)
30
+ config.method("#{name}=").call(val)
31
+ end
32
+
33
+ def set(config, val, mark_configured: true)
34
+ set_raw(config, parse.call(val))
35
+ config.method("#{name}_configured=").call(true) if mark_configured
36
+ end
37
+
38
+ def set_to_default(config)
39
+ set(config, default, mark_configured: false) if default
40
+ end
41
+
42
+ def set_if_unconfigured(config, val)
43
+ set(config, val) unless configured?(config)
44
+ end
45
+
46
+ def configured?(config)
47
+ config.method("#{name}_configured").call
48
+ end
49
+
50
+ def attach_to_option_parser(config, opt)
51
+ return if command_line.empty?
52
+ opt.on(*command_line, *description) do |val|
53
+ set(config, val)
54
+ end
55
+ end
59
56
  end
57
+ # rubocop:enable Style/AccessorMethodName
60
58
 
61
- def podspec=(podspec)
62
- @podspec = PodspecDocumenter.configure(self, podspec)
59
+ def self.config_attr(name, **opts)
60
+ attr_accessor name
61
+ attr_accessor "#{name}_configured"
62
+ @all_config_attrs ||= []
63
+ @all_config_attrs << Attribute.new(name, **opts)
64
+ end
65
+
66
+ class << self
67
+ attr_reader :all_config_attrs
68
+ end
69
+
70
+ # ──────── Build ────────
71
+
72
+ # rubocop:disable Style/AlignParameters
73
+
74
+ config_attr :output,
75
+ description: 'Folder to output the HTML docs to',
76
+ command_line: ['-o', '--output FOLDER'],
77
+ default: 'docs',
78
+ parse: ->(o) { Pathname(o) }
79
+
80
+ config_attr :clean,
81
+ command_line: ['-c', '--[no-]clean'],
82
+ description: ['Delete contents of output directory before running. ',
83
+ 'WARNING: If --output is set to ~/Desktop, this will '\
84
+ 'delete the ~/Desktop directory.'],
85
+ default: false
86
+
87
+ config_attr :objc_mode,
88
+ command_line: '--[no-]objc',
89
+ description: 'Generate docs for Objective-C.',
90
+ default: false
91
+
92
+ config_attr :umbrella_header,
93
+ command_line: '--umbrella-header PATH',
94
+ description: 'Umbrella header for your Objective-C framework.',
95
+ parse: ->(uh) { Pathname(uh) }
96
+
97
+ config_attr :framework_root,
98
+ command_line: '--framework-root PATH',
99
+ description: 'The root path to your Objective-C framework.',
100
+ parse: ->(fr) { Pathname(fr) }
101
+
102
+ config_attr :config_file,
103
+ command_line: '--config PATH',
104
+ description: ['Configuration file (.yaml or .json)',
105
+ 'Default: .jazzy.yaml in source directory or ancestor'],
106
+ parse: ->(cf) { Pathname(cf) }
107
+
108
+ config_attr :xcodebuild_arguments,
109
+ command_line: ['-x', '--xcodebuild-arguments arg1,arg2,…argN', Array],
110
+ description: 'Arguments to forward to xcodebuild',
111
+ default: []
112
+
113
+ config_attr :sourcekitten_sourcefile,
114
+ command_line: ['-s', '--sourcekitten-sourcefile FILEPATH'],
115
+ description: 'File generated from sourcekitten output to parse',
116
+ parse: ->(s) { Pathname(s) }
117
+
118
+ config_attr :source_directory,
119
+ command_line: '--source-directory DIRPATH',
120
+ description: 'The directory that contains the source to be documented',
121
+ default: Pathname.pwd,
122
+ parse: ->(sd) { Pathname(sd) }
123
+
124
+ config_attr :excluded_files,
125
+ command_line: ['-e', '--exclude file1,file2,…fileN', Array],
126
+ description: 'Files to be excluded from documentation',
127
+ default: [],
128
+ parse: ->(files) do
129
+ files.map { |f| File.expand_path(f) }
130
+ end
131
+
132
+ config_attr :swift_version,
133
+ command_line: '--swift-version VERSION',
134
+ default: '2.1'
135
+
136
+ # ──────── Metadata ────────
137
+
138
+ config_attr :author_name,
139
+ command_line: ['-a', '--author AUTHOR_NAME'],
140
+ description: 'Name of author to attribute in docs (e.g. Realm)',
141
+ default: ''
142
+
143
+ config_attr :author_url,
144
+ command_line: ['-u', '--author_url URL'],
145
+ description: 'Author URL of this project (e.g. http://realm.io)',
146
+ default: '',
147
+ parse: ->(u) { URI(u) }
148
+
149
+ config_attr :module_name,
150
+ command_line: ['-m', '--module MODULE_NAME'],
151
+ description: 'Name of module being documented. (e.g. RealmSwift)',
152
+ default: ''
153
+
154
+ config_attr :version,
155
+ command_line: '--module-version VERSION',
156
+ description: 'module version. will be used when generating docset',
157
+ default: '1.0'
158
+
159
+ config_attr :copyright,
160
+ command_line: '--copyright COPYRIGHT_MARKDOWN',
161
+ description: 'copyright markdown rendered at the bottom of the docs pages'
162
+
163
+ config_attr :readme_path,
164
+ command_line: '--readme FILEPATH',
165
+ description: 'The path to a markdown README file',
166
+ parse: ->(rp) { Pathname(rp) }
167
+
168
+ config_attr :podspec,
169
+ command_line: '--podspec FILEPATH',
170
+ parse: ->(ps) { PodspecDocumenter.create_podspec(Pathname(ps)) if ps },
171
+ default: Dir['*.podspec{,.json}'].first
172
+
173
+ config_attr :docset_platform, default: 'jazzy'
174
+
175
+ config_attr :docset_icon,
176
+ command_line: '--docset-icon FILEPATH',
177
+ parse: ->(di) { Pathname(di) }
178
+
179
+ config_attr :docset_path,
180
+ command_line: '--docset-path DIRPATH',
181
+ description: 'The relative path for the generated docset'
182
+
183
+ # ──────── URLs ────────
184
+
185
+ config_attr :root_url,
186
+ command_line: ['-r', '--root-url URL'],
187
+ description: 'Absolute URL root where these docs will be stored',
188
+ parse: ->(r) { URI(r) }
189
+
190
+ config_attr :dash_url,
191
+ command_line: ['-d', '--dash_url URL'],
192
+ description: 'Location of the dash XML feed '\
193
+ 'e.g. http://realm.io/docsets/realm.xml)',
194
+ parse: ->(d) { URI(d) }
195
+
196
+ config_attr :github_url,
197
+ command_line: ['-g', '--github_url URL'],
198
+ description: 'GitHub URL of this project (e.g. '\
199
+ 'https://github.com/realm/realm-cocoa)',
200
+ parse: ->(g) { URI(g) }
201
+
202
+ config_attr :github_file_prefix,
203
+ command_line: '--github-file-prefix PREFIX',
204
+ description: 'GitHub URL file prefix of this project (e.g. '\
205
+ 'https://github.com/realm/realm-cocoa/tree/v0.87.1)'
206
+
207
+ # ──────── Doc generation options ────────
208
+
209
+ config_attr :min_acl,
210
+ command_line: '--min-acl [private | internal | public]',
211
+ description: 'minimum access control level to document',
212
+ default: 'public',
213
+ parse: ->(acl) do
214
+ SourceDeclaration::AccessControlLevel.from_human_string(acl)
215
+ end
216
+
217
+ config_attr :skip_undocumented,
218
+ command_line: '--[no-]skip-undocumented',
219
+ description: "Don't document declarations that have no documentation '\
220
+ 'comments.",
221
+ default: false
222
+
223
+ config_attr :hide_documentation_coverage,
224
+ command_line: '--[no-]hide-documentation-coverage',
225
+ description: "Hide \"(X\% documented)\" from the generated documents",
226
+ default: false
227
+
228
+ config_attr :custom_categories,
229
+ description: ['Custom navigation categories to replace the standard '\
230
+ '“Classes, Protocols, etc.”', 'Types not explicitly named '\
231
+ 'in a custom category appear in generic groups at the end.',
232
+ 'Example: http://git.io/vcTZm'],
233
+ default: []
234
+
235
+ config_attr :template_directory,
236
+ command_line: ['-t', '--template-directory DIRPATH'],
237
+ description: 'The directory that contains the mustache templates to use',
238
+ default: Pathname(__FILE__).parent + 'templates',
239
+ parse: ->(td) { Pathname(td) }
240
+
241
+ config_attr :assets_directory,
242
+ command_line: '--assets-directory DIRPATH',
243
+ description: 'The directory that contains the assets (CSS, JS, images) '\
244
+ 'used by the templates',
245
+ default: Pathname(__FILE__).parent + 'assets',
246
+ parse: ->(ad) { Pathname(ad) }
247
+
248
+ # rubocop:enable Style/AlignParameters
249
+
250
+ def initialize
251
+ self.class.all_config_attrs.each do |attr|
252
+ attr.set_to_default(self)
253
+ end
63
254
  end
64
255
 
65
256
  def template_directory=(template_directory)
@@ -70,173 +261,142 @@ module Jazzy
70
261
  # rubocop:disable Metrics/MethodLength
71
262
  def self.parse!
72
263
  config = new
264
+ config.parse_command_line
265
+ config.parse_config_file
266
+ PodspecDocumenter.apply_config_defaults(config.podspec, config)
267
+
268
+ if config.root_url
269
+ config.dash_url ||= URI.join(
270
+ config.root_url,
271
+ "docsets/#{config.module_name}.xml")
272
+ end
273
+
274
+ config
275
+ end
276
+
277
+ def parse_command_line
73
278
  OptionParser.new do |opt|
74
279
  opt.banner = 'Usage: jazzy'
75
280
  opt.separator ''
76
281
  opt.separator 'Options'
77
282
 
78
- opt.on('-o', '--output FOLDER',
79
- 'Folder to output the HTML docs to') do |output|
80
- config.output = Pathname(output)
81
- end
82
-
83
- opt.on('-c', '--[no-]clean',
84
- 'Delete contents of output directory before running.',
85
- 'WARNING: If --output is set to ~/Desktop, this will delete the \
86
- ~/Desktop directory.') do |clean|
87
- config.clean = clean
88
- end
89
-
90
- opt.on('-x', '--xcodebuild-arguments arg1,arg2,…argN', Array,
91
- 'Arguments to forward to xcodebuild') do |args|
92
- config.xcodebuild_arguments = args
93
- end
94
-
95
- opt.on('-a', '--author AUTHOR_NAME',
96
- 'Name of author to attribute in docs (i.e. Realm)') do |a|
97
- config.author_name = a
98
- end
99
-
100
- opt.on('-u', '--author_url URL',
101
- 'Author URL of this project (i.e. http://realm.io)') do |u|
102
- config.author_url = URI(u)
103
- end
104
-
105
- opt.on('-m', '--module MODULE_NAME',
106
- 'Name of module being documented. (i.e. RealmSwift)') do |m|
107
- config.module_name = m
108
- end
109
-
110
- opt.on('-d', '--dash_url URL',
111
- 'Location of the dash XML feed \
112
- (i.e. http://realm.io/docsets/realm.xml') do |d|
113
- config.dash_url = URI(d)
283
+ self.class.all_config_attrs.each do |attr|
284
+ attr.attach_to_option_parser(self, opt)
114
285
  end
115
286
 
116
- opt.on('-g', '--github_url URL',
117
- 'GitHub URL of this project (i.e. \
118
- https://github.com/realm/realm-cocoa)') do |g|
119
- config.github_url = URI(g)
120
- end
121
-
122
- opt.on('--github-file-prefix PREFIX',
123
- 'GitHub URL file prefix of this project (i.e. \
124
- https://github.com/realm/realm-cocoa/tree/v0.87.1)') do |g|
125
- config.github_file_prefix = g
126
- end
127
-
128
- opt.on('-s', '--sourcekitten-sourcefile FILEPATH',
129
- 'File generated from sourcekitten output to parse') do |s|
130
- config.sourcekitten_sourcefile = Pathname(s)
287
+ opt.on('-v', '--version', 'Print version number') do
288
+ puts 'jazzy version: ' + Jazzy::VERSION
289
+ exit
131
290
  end
132
291
 
133
- opt.on('-r', '--root-url URL',
134
- 'Absolute URL root where these docs will be stored') do |r|
135
- config.root_url = URI(r)
136
- if !config.dash_url && config.root_url
137
- config.dash_url = URI.join(r, "docsets/#{config.module_name}.xml")
292
+ opt.on('-h', '--help [TOPIC]', 'Available topics:',
293
+ ' usage Command line options (this help message)',
294
+ ' config Configuration file options',
295
+ '...or an option keyword, e.g. "dash"') do |topic|
296
+ case topic
297
+ when 'usage', nil
298
+ puts opt
299
+ when 'config'
300
+ print_config_file_help
301
+ else
302
+ print_option_help(topic)
138
303
  end
304
+ exit
139
305
  end
306
+ end.parse!
140
307
 
141
- opt.on('--module-version VERSION',
142
- 'module version. will be used when generating docset') do |mv|
143
- config.version = mv
144
- end
308
+ expand_paths(Pathname.pwd)
309
+ end
145
310
 
146
- opt.on('--min-acl [private | internal | public]',
147
- 'minimum access control level to document \
148
- (default is public)') do |acl|
149
- if acl == 'private'
150
- config.min_acl = SourceDeclaration::AccessControlLevel.private
151
- elsif acl == 'internal'
152
- config.min_acl = SourceDeclaration::AccessControlLevel.internal
153
- end
154
- end
311
+ def parse_config_file
312
+ config_path = locate_config_file
313
+ return unless config_path
155
314
 
156
- opt.on('--[no-]skip-undocumented',
157
- "Don't document declarations that have no documentation \
158
- comments.",
159
- ) do |skip_undocumented|
160
- config.skip_undocumented = skip_undocumented
315
+ puts "Using config file #{config_path}"
316
+ config_file = read_config_file(config_path)
317
+ self.class.all_config_attrs.each do |attr|
318
+ key = attr.name.to_s
319
+ if config_file.key?(key)
320
+ attr.set_if_unconfigured(self, config_file[key])
161
321
  end
322
+ end
162
323
 
163
- opt.on('--[no-]hide-documentation-coverage',
164
- "Hide \"(X\% documented)\" from the generated documents",
165
- ) do |hide_documentation_coverage|
166
- config.hide_documentation_coverage = hide_documentation_coverage
167
- end
324
+ expand_paths(config_path.parent)
325
+ end
168
326
 
169
- opt.on('--podspec FILEPATH') do |podspec|
170
- config.podspec = Pathname(podspec)
171
- end
327
+ def locate_config_file
328
+ return config_file if config_file
172
329
 
173
- opt.on('--docset-icon FILEPATH') do |docset_icon|
174
- config.docset_icon = Pathname(docset_icon)
175
- end
330
+ source_directory.ascend do |dir|
331
+ candidate = dir.join('.jazzy.yaml')
332
+ return candidate if candidate.exist?
333
+ end
176
334
 
177
- opt.on('--docset-path DIRPATH', 'The relative path for the generated ' \
178
- 'docset') do |docset_path|
179
- config.docset_path = docset_path
180
- end
335
+ nil
336
+ end
181
337
 
182
- opt.on('--source-directory DIRPATH', 'The directory that contains ' \
183
- 'the source to be documented') do |source_directory|
184
- config.source_directory = Pathname(source_directory)
185
- end
338
+ def read_config_file(file)
339
+ case File.extname(file)
340
+ when '.json' then JSON.parse(File.read(file))
341
+ when '.yaml', '.yml' then YAML.load(File.read(file))
342
+ else raise "Config file must be .yaml or .json, but got #{file.inspect}"
343
+ end
344
+ end
186
345
 
187
- opt.on('t', '--template-directory DIRPATH', 'The directory that ' \
188
- 'contains the mustache templates to use') do |template_directory|
189
- config.template_directory = Pathname(template_directory)
346
+ def expand_paths(base_path)
347
+ self.class.all_config_attrs.each do |attr|
348
+ val = attr.get(self)
349
+ if val.respond_to?(:expand_path)
350
+ attr.set_raw(self, val.expand_path(base_path))
190
351
  end
352
+ end
353
+ end
191
354
 
192
- opt.on('--swift-version VERSION') do |swift_version|
193
- config.swift_version = swift_version
194
- end
355
+ def print_config_file_help
356
+ puts <<-_EOS_
195
357
 
196
- opt.on('--assets-directory DIRPATH', 'The directory that contains ' \
197
- 'the assets (CSS, JS, images) to use') do |assets_directory|
198
- config.assets_directory = Pathname(assets_directory)
199
- end
358
+ By default, jazzy looks for a file named ".jazzy.yaml" in the source
359
+ directory and its ancestors. You can override the config file location
360
+ with --config.
200
361
 
201
- opt.on('--readme FILEPATH',
202
- 'The path to a markdown README file') do |readme|
203
- config.readme_path = Pathname(readme)
204
- end
362
+ (The source directory is the current working directory by default.
363
+ You can override that with --source-directory.)
205
364
 
206
- opt.on('-e', '--exclude file1,file2,…fileN', Array,
207
- 'Files to be excluded from documentation') do |files|
208
- config.excluded_files = files.map { |f| File.expand_path(f) }
209
- end
365
+ The config file can be in YAML or JSON format. Available options are:
210
366
 
211
- opt.on('--categories file',
212
- 'JSON or YAML file with custom groupings') do |file|
213
- config.custom_categories = parse_config_file(file)
214
- end
367
+ _EOS_
368
+ .gsub(/^ +/, '')
215
369
 
216
- opt.on('-v', '--version', 'Print version number') do
217
- puts 'jazzy version: ' + Jazzy::VERSION
218
- exit
219
- end
370
+ print_option_help
371
+ end
220
372
 
221
- opt.on('--copyright COPYRIGHT_MARKDOWN', 'copyright markdown ' \
222
- 'rendered at the bottom of the docs pages') do |copyright|
223
- config.copyright = copyright
373
+ def print_option_help(topic = '')
374
+ found = false
375
+ self.class.all_config_attrs.each do |attr|
376
+ match = ([attr.name] + attr.command_line).any? do |opt|
377
+ opt.to_s.include?(topic)
224
378
  end
225
-
226
- opt.on('-h', '--help', 'Print this help message') do
227
- puts opt
228
- exit
379
+ if match
380
+ found = true
381
+ puts
382
+ puts attr.name.to_s.tr('_', ' ').upcase
383
+ puts
384
+ puts " Config file: #{attr.name}"
385
+ cmd_line_forms = attr.command_line.select { |opt| opt.is_a?(String) }
386
+ if cmd_line_forms.any?
387
+ puts " Command line: #{cmd_line_forms.join(', ')}"
388
+ end
389
+ puts
390
+ print_attr_description(attr)
229
391
  end
230
- end.parse!
231
-
232
- config
392
+ end
393
+ warn "Unknown help topic #{topic.inspect}" unless found
233
394
  end
234
395
 
235
- def self.parse_config_file(file)
236
- case File.extname(file)
237
- when '.json' then JSON.parse(File.read(file))
238
- when '.yaml', '.yml' then YAML.load(File.read(file))
239
- else raise "Config file must be .yaml or .json, but got #{file.inspect}"
396
+ def print_attr_description(attr)
397
+ attr.description.each { |line| puts " #{line}" }
398
+ if attr.default && attr.default != ''
399
+ puts " Default: #{attr.default}"
240
400
  end
241
401
  end
242
402