jazzy 0.3.2 → 0.4.0

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