yard 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of yard might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 994e4c83b93e9b6c520138f2d8a221b25ab95ca4
4
- data.tar.gz: 82668951125bfa84bb79b636c130af43a6daf772
3
+ metadata.gz: f93ca569b327f662d35892e83a4799a91868da56
4
+ data.tar.gz: c185c90879b8b862d40bb3eee2da95e67311e568
5
5
  SHA512:
6
- metadata.gz: f41d5b06ef5224e1f4ebdc2278323df57e8c70ccd13105827905494c1e4ea81e170c20d9fe797e362dd45e045f4a17c700818e0cba2503fbf8c9178ffdac6392
7
- data.tar.gz: 99e47e1a3ea86721d389ee3215d6adf643e0e1becc851f2ea0e4c1f7e26224d9d61e30530533c776c094d5e9035b5e43f45241e72e9f76cf59ca362526730f07
6
+ metadata.gz: 1f0cf4b6767842dcd90879cd6039e510767af156c17f6722b46028d239bca925dc854b5399009a27615761a50875523f7e2aa27f89b4e6f5f7d9d101d48f9ef2
7
+ data.tar.gz: 85d0822f567fb4caad941758e54f7805bceae24dbe1f84a31c4c0ae79658ddafb152c1646e3d65201847a69288133d7227a442825fbf0560b8399ff26714a6e6
@@ -1,3 +1,14 @@
1
+ # 0.9.5 - July 22nd, 2016
2
+
3
+ - `yard doc` will now generate `.yardoc/processing` and `.yardoc/complete` files
4
+ to allow other tools to properly detect when YARD is in the middle of parsing
5
+ source files, and when it has completed writing the database.
6
+ - Added support for on-demand generation of LibraryVersion objects using the
7
+ `:disk` source type. LibraryVersion objects pointing to a .yardoc database
8
+ directory will now auto-generate if there is a `source_path` attached.
9
+ - Added warning for macros attached to non-method objects.
10
+ - Fixed a few more parsing errors.
11
+
1
12
  # 0.9.4 - July 21st, 2016
2
13
 
3
14
  - Minor Ruby file parsing and CSS bug fixes.
@@ -35,9 +35,10 @@ module YARD
35
35
  next unless yfile
36
36
  next unless File.directory?(spec.full_gem_path)
37
37
  Registry.clear
38
- Dir.chdir(spec.full_gem_path)
39
- log.info "Building yardoc index for gem: #{spec.full_name}"
40
- Yardoc.run('--no-stats', '-n', '-b', yfile)
38
+ Dir.chdir(spec.full_gem_path) do
39
+ log.info "Building yardoc index for gem: #{spec.full_name}"
40
+ Yardoc.run('--no-stats', '-n', '-b', yfile)
41
+ end
41
42
  end
42
43
  end
43
44
  end
@@ -86,7 +86,7 @@ module YARD
86
86
  libver = create_library_version_if_yardopts_exist(library, pwd)
87
87
 
88
88
  # Check default location
89
- yfile = File.join(pwd, '.yardoc')
89
+ yfile = File.join(pwd, Registry::DEFAULT_YARDOC_FILE)
90
90
  libver ||= YARD::Server::LibraryVersion.new(library, nil, yfile)
91
91
  end
92
92
 
@@ -213,8 +213,9 @@ module YARD
213
213
  add_libraries([File.basename(Dir.pwd), nil])
214
214
 
215
215
  # Generate doc for first time
216
+ # This is not necessary but makes for a better first-run experience
216
217
  libver = libraries.empty? ? nil : libraries.values.first.first
217
- if libver and !File.exist?(libver.yardoc_file)
218
+ if libver and !libver.ready?
218
219
  generate_doc_for_first_time(libver)
219
220
  end
220
221
  else
@@ -246,8 +246,15 @@ module YARD
246
246
  Registry.load
247
247
  checksums = Registry.checksums.dup
248
248
  end
249
- YARD.parse(files, excluded)
250
- Registry.save(use_cache) if save_yardoc
249
+
250
+ if save_yardoc
251
+ Registry.lock_for_writing do
252
+ YARD.parse(files, excluded)
253
+ Registry.save(use_cache)
254
+ end
255
+ else
256
+ YARD.parse(files, excluded)
257
+ end
251
258
 
252
259
  if generate
253
260
  run_generate(checksums)
@@ -94,6 +94,10 @@ module YARD::Handlers::Ruby::DecoratorHandlerMethods
94
94
  name = node.jump(:ident, :string_content, :const).source
95
95
  end
96
96
 
97
+ if name.nil?
98
+ raise YARD::Parser::UndocumentableError, 'statement, cannot determine method name'
99
+ end
100
+
97
101
  method = YARD::CodeObjects::Proxy.new(
98
102
  namespace,
99
103
  (scope == :instance ? '#' : '.') + name.to_s,
@@ -47,6 +47,7 @@ module YARD
47
47
  @encoding_line = nil
48
48
  @frozen_string_line = nil
49
49
  @file_encoding = nil
50
+ @newline = true
50
51
  end
51
52
 
52
53
  def parse
@@ -199,6 +199,20 @@ module YARD
199
199
  self.thread_local_store = RegistryStore.new
200
200
  end
201
201
 
202
+ # Creates a pessmistic transactional lock on the database for writing.
203
+ # Use with {YARD.parse} to ensure the database is not written multiple
204
+ # times.
205
+ #
206
+ # @see locked_for_writing?
207
+ def lock_for_writing(file = yardoc_file, &block)
208
+ thread_local_store.lock_for_writing(file, &block)
209
+ end
210
+
211
+ # (see Serializers::YardocSerializer#locked_for_writing?)
212
+ def locked_for_writing?(file = yardoc_file)
213
+ thread_local_store.locked_for_writing?(file)
214
+ end
215
+
202
216
  # @group Accessing Objects in the Registry
203
217
 
204
218
  # Iterates over {all} with no arguments
@@ -375,8 +389,11 @@ module YARD
375
389
  def global_yardoc_file(spec, for_writing = false)
376
390
  path = spec.doc_dir
377
391
  yfile = spec.doc_dir(DEFAULT_YARDOC_FILE)
378
- if for_writing && File.writable?(path)
379
- return yfile
392
+ if for_writing
393
+ if File.writable?(path) ||
394
+ (!File.directory?(path) && File.writable?(File.dirname(path)))
395
+ return yfile
396
+ end
380
397
  elsif !for_writing && File.exist?(yfile)
381
398
  return yfile
382
399
  end
@@ -187,9 +187,22 @@ module YARD
187
187
  write_proxy_types
188
188
  write_object_types
189
189
  write_checksums
190
+ write_complete_lock
190
191
  true
191
192
  end
192
193
 
194
+ # (see Serializers::YardocSerializer#lock_for_writing)
195
+ # @param file [String] if supplied, the path to the database
196
+ def lock_for_writing(file = nil, &block)
197
+ Serializers::YardocSerializer.new(file || @file).lock_for_writing(&block)
198
+ end
199
+
200
+ # (see Serializers::YardocSerializer#locked_for_writing?)
201
+ # @param file [String] if supplied, the path to the database
202
+ def locked_for_writing?(file = nil)
203
+ Serializers::YardocSerializer.new(file || @file).locked_for_writing?
204
+ end
205
+
193
206
  # Deletes the .yardoc database on disk
194
207
  #
195
208
  # @param [Boolean] force if force is not set to true, the file/directory
@@ -315,5 +328,9 @@ module YARD
315
328
  @checksums.each {|k, v| f.puts("#{k} #{v}") }
316
329
  end
317
330
  end
331
+
332
+ def write_complete_lock
333
+ File.open!(@serializer.complete_lock_path, 'w') {}
334
+ end
318
335
  end
319
336
  end
@@ -36,6 +36,29 @@ module YARD
36
36
  def proxy_types_path; File.join(basepath, 'proxy_types') end
37
37
  def checksums_path; File.join(basepath, 'checksums') end
38
38
  def object_types_path; File.join(basepath, 'object_types') end
39
+ def complete_lock_path; File.join(basepath, 'complete') end
40
+ def processing_path; File.join(basepath, 'processing') end
41
+
42
+ def complete?
43
+ File.exist?(complete_lock_path) && !locked_for_writing?
44
+ end
45
+
46
+ # Creates a pessmistic transactional lock on the database for writing.
47
+ # Use with {YARD.parse} to ensure the database is not written multiple
48
+ # times.
49
+ #
50
+ # @see #locked_for_writing?
51
+ def lock_for_writing(&block)
52
+ File.open!(processing_path, 'w') {}
53
+ yield
54
+ ensure
55
+ File.unlink(processing_path) if File.exist?(processing_path)
56
+ end
57
+
58
+ # @return [Boolean] whether the database is currently locked for writing
59
+ def locked_for_writing?
60
+ File.exist?(processing_path)
61
+ end
39
62
 
40
63
  def serialized_path(object)
41
64
  path = case object
@@ -106,7 +106,7 @@ module YARD
106
106
  end
107
107
 
108
108
  def load_yardoc
109
- raise LibraryNotPreparedError unless library.yardoc_file
109
+ raise LibraryNotPreparedError unless library.ready?
110
110
  if Thread.current[:__yard_last_yardoc__] == library.yardoc_file
111
111
  log.debug "Reusing yardoc file: #{library.yardoc_file}"
112
112
  return
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'thread'
2
3
 
3
4
  module YARD
4
5
  module Server
@@ -144,6 +145,13 @@ module YARD
144
145
  alias == eql?
145
146
  alias equal? eql?
146
147
 
148
+ # @return [Boolean] whether the library has been completely processed
149
+ # and is ready to be served
150
+ def ready?
151
+ return false if yardoc_file.nil?
152
+ serializer.complete?
153
+ end
154
+
147
155
  # @note You should not directly override this method. Instead, implement
148
156
  # +load_yardoc_from_SOURCENAME+ when implementing loading for a specific
149
157
  # source type. See the {LibraryVersion} documentation for "Implementing
@@ -160,7 +168,7 @@ module YARD
160
168
  # begin preparing the library for subsequent requests, although this
161
169
  # is not necessary.
162
170
  def prepare!
163
- return if yardoc_file
171
+ return if ready?
164
172
  meth = "load_yardoc_from_#{source}"
165
173
  send(meth) if respond_to?(meth, true)
166
174
  end
@@ -170,16 +178,31 @@ module YARD
170
178
  # @return [nil] if there is no installed gem for the library
171
179
  def gemspec
172
180
  ver = version ? "= #{version}" : ">= 0"
173
- Gem.source_index.find_name(name, ver).first
181
+ Gem.source_index.find_name(name, ver).last
174
182
  end
175
183
 
176
184
  protected
177
185
 
186
+ @@chdir_mutex = Mutex.new
187
+
178
188
  # Called when a library of source type "disk" is to be prepared. In this
179
- # case, the {#yardoc_file} should already be set, so nothing needs to be
180
- # done.
189
+ # case, the {#yardoc_file} should already be set, but the library may not
190
+ # be prepared. Run preparation if not done.
191
+ #
192
+ # @raise [LibraryNotPreparedError] if the yardoc file has not been
193
+ # prepared.
181
194
  def load_yardoc_from_disk
182
- nil
195
+ return if ready?
196
+
197
+ @@chdir_mutex.synchronize do
198
+ Dir.chdir(source_path_for_disk) do
199
+ Thread.new do
200
+ CLI::Yardoc.run('--no-stats', '-n', '-b', yardoc_file)
201
+ end
202
+ end
203
+ end
204
+
205
+ raise LibraryNotPreparedError
183
206
  end
184
207
 
185
208
  # Called when a library of source type "gem" is to be prepared. In this
@@ -192,18 +215,18 @@ module YARD
192
215
  require 'rubygems'
193
216
  ver = version ? "= #{version}" : ">= 0"
194
217
  self.yardoc_file = Registry.yardoc_file_for_gem(name, ver)
195
- unless yardoc_file && File.directory?(yardoc_file)
218
+ return if ready?
219
+
220
+ @@chdir_mutex.synchronize do
196
221
  Thread.new do
197
222
  # Build gem docs on demand
198
223
  log.debug "Building gem docs for #{to_s(false)}"
199
224
  CLI::Gems.run(name, ver)
200
225
  self.yardoc_file = Registry.yardoc_file_for_gem(name, ver)
201
- FileUtils.touch(File.join(yardoc_file, 'complete'))
202
226
  end
203
227
  end
204
- unless yardoc_file && File.exist?(File.join(yardoc_file, 'complete'))
205
- raise LibraryNotPreparedError
206
- end
228
+
229
+ raise LibraryNotPreparedError
207
230
  end
208
231
 
209
232
  # @return [String] the source path for a disk source
@@ -222,6 +245,11 @@ module YARD
222
245
  meth = "source_path_for_#{source}"
223
246
  send(meth) if respond_to?(meth, true)
224
247
  end
248
+
249
+ def serializer
250
+ return if yardoc_file.nil?
251
+ @serializer ||= Serializers::YardocSerializer.new(yardoc_file)
252
+ end
225
253
  end
226
254
  end
227
255
  end
@@ -299,8 +299,14 @@ module YARD
299
299
  def find_or_create
300
300
  if new? || attach?
301
301
  if handler && attach?
302
- obj = object ? object :
303
- P("#{handler.namespace}.#{handler.caller_method}")
302
+ if object && object.is_a?(CodeObjects::NamespaceObject)
303
+ log.warn "Attaching macros to non-methods is unsupported, ignoring: " +
304
+ "#{object.path} (#{handler.parser.file}:#{handler.statement.line})"
305
+ obj = nil
306
+ else
307
+ obj = object ? object :
308
+ P("#{handler.namespace}.#{handler.caller_method}")
309
+ end
304
310
  else
305
311
  obj = nil
306
312
  end
@@ -1,3 +1,3 @@
1
1
  module YARD
2
- VERSION = '0.9.4'
2
+ VERSION = '0.9.5'
3
3
  end
@@ -19,11 +19,11 @@ describe YARD::CLI::Gems do
19
19
 
20
20
  def build_specs(*specs)
21
21
  specs.each do |themock|
22
- expect(Registry).to receive(:yardoc_file_for_gem).with(themock.name, "= #{themock.version}").and_return(themock.yardoc_file)
23
- expect(File).to receive(:directory?).with(themock.yardoc_file).and_return(@rebuild)
24
- expect(File).to receive(:directory?).with(themock.full_gem_path).and_return(true)
25
- expect(Registry).to receive(:yardoc_file_for_gem).with(themock.name, "= #{themock.version}", true).and_return(themock.yardoc_file)
26
- expect(Dir).to receive(:chdir).with(themock.full_gem_path)
22
+ allow(Registry).to receive(:yardoc_file_for_gem).with(themock.name, "= #{themock.version}").and_return(themock.yardoc_file)
23
+ allow(File).to receive(:directory?).with(themock.yardoc_file).and_return(@rebuild)
24
+ allow(File).to receive(:directory?).with(themock.full_gem_path).and_return(true)
25
+ allow(Registry).to receive(:yardoc_file_for_gem).with(themock.name, "= #{themock.version}", true).and_return(themock.yardoc_file)
26
+ expect(Dir).to receive(:chdir).with(themock.full_gem_path).and_yield
27
27
  end
28
28
  expect(Registry).to receive(:clear).exactly(specs.size).times
29
29
  expect(CLI::Yardoc).to receive(:run).exactly(specs.size).times
@@ -83,7 +83,9 @@ describe YARD::CLI::Server do
83
83
  context 'when .yardopts file exists' do
84
84
  before :each do
85
85
  Registry.yardoc_file = Registry::DEFAULT_YARDOC_FILE
86
+ allow(File).to receive(:exist?).with(/\.yardoc\/complete$/).and_return(false)
86
87
  allow(Dir).to receive(:pwd).and_return('/path/to/bar')
88
+ allow(Dir).to receive(:chdir).and_yield
87
89
  @name = 'bar'
88
90
  end
89
91
 
@@ -95,6 +97,7 @@ describe YARD::CLI::Server do
95
97
  end
96
98
 
97
99
  it "uses the yardoc db location specified by .yardopts" do
100
+ allow(File).to receive(:exist?).with(/\/foo\/complete$/).and_return(false)
98
101
  mock_file '/path/to/bar/.yardopts', '--db foo'
99
102
  @libraries[@name] = [Server::LibraryVersion.new(@name, nil, File.expand_path('/path/to/bar/foo'))]
100
103
  @libraries.values[0][0].source_path = File.expand_path('/path/to/bar')
@@ -111,6 +114,7 @@ describe YARD::CLI::Server do
111
114
 
112
115
  context "when .yardopts file doesn't exist" do
113
116
  before :each do
117
+ allow(File).to receive(:exist?).with(/\.yardoc\/complete$/).and_return(false)
114
118
  allow(File).to receive(:exist?).with(/^(.*[\\\/])?\.yardopts$/).and_return(false)
115
119
  end
116
120
 
@@ -143,6 +147,7 @@ describe YARD::CLI::Server do
143
147
 
144
148
  describe "General options" do
145
149
  before do
150
+ allow(File).to receive(:exist?).with(/\.yardoc\/complete$/).and_return(false)
146
151
  allow(File).to receive(:exist?).with(/\.yardopts$/).and_return(false)
147
152
  end
148
153
 
@@ -12,6 +12,7 @@ describe YARD::CLI::Yardoc do
12
12
  allow(YARD).to receive(:parse)
13
13
  allow(Registry).to receive(:load)
14
14
  allow(Registry).to receive(:save)
15
+ allow(File).to receive(:open!)
15
16
  end
16
17
 
17
18
  describe "Defaults" do
@@ -803,5 +804,15 @@ describe YARD::CLI::Yardoc do
803
804
  expect(@yardoc).not_to receive(:parse_arguments)
804
805
  @yardoc.run(nil)
805
806
  end
807
+
808
+ it "creates processing lock if saving" do
809
+ expect(Registry).to receive(:lock_for_writing).and_yield
810
+ @yardoc.run
811
+ end
812
+
813
+ it "does not create processing lock if not saving" do
814
+ expect(Registry).not_to receive(:lock_for_writing)
815
+ @yardoc.run('--no-save')
816
+ end
806
817
  end
807
818
  end
@@ -194,6 +194,10 @@ describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}DSLHandler" do
194
194
  eof
195
195
  end
196
196
 
197
+ it "warns on unparseable DSL statements" do
198
+ undoc_error "private(*foo(bar))"
199
+ end if HAVE_RIPPER
200
+
197
201
  # @note Currently unsupported behavior. Overriding a macro on an alias will
198
202
  # not work until macro lookups can be done by caller_method directly.
199
203
  # @todo optimize MacroObject lookup to work by caller name, not macro name.
@@ -403,6 +403,18 @@ eof
403
403
  expect(Registry.at("Foo::Bar#foo").docstring).to eq "Docstring2"
404
404
  end
405
405
 
406
+ it "supports #{type} statements at start of source" do
407
+ Registry.clear
408
+ YARD.parse_string <<-eof
409
+ #{type} condition?
410
+ class Foo; def bar; #{type} true; end end end
411
+ end
412
+ eof
413
+
414
+ expect(log.io.string).to eq ""
415
+ expect(Registry.at('Foo#bar')).not_to eq nil
416
+ end
417
+
406
418
  it "can handle complex non-modifier '#{type}' statements" do
407
419
  Registry.clear
408
420
  YARD.parse_string <<-eof
@@ -414,6 +426,7 @@ eof
414
426
  end
415
427
  eof
416
428
 
429
+ expect(log.io.string).to eq ""
417
430
  expect(Registry.at('Foo#initialize')).not_to eq nil
418
431
  end
419
432
 
@@ -66,6 +66,14 @@ describe YARD::Registry do
66
66
  expect(Registry.yardoc_file_for_gem('foo', '>= 0', true)).to eq '/path/to/foo/doc/.yardoc'
67
67
  end
68
68
 
69
+ it "returns new global .yardoc path for gem if for_writing=true and parent dir is writable (but dir does not exist)" do
70
+ expect(File).to receive(:writable?).with(@gem.doc_dir).and_return(false)
71
+ expect(File).to receive(:directory?).with(@gem.doc_dir).and_return(false)
72
+ expect(File).to receive(:writable?).with(File.dirname(@gem.doc_dir)).and_return(true)
73
+ expect(Gem.source_index).to receive(:find_name).with('foo', '>= 0').and_return([@gem])
74
+ expect(Registry.yardoc_file_for_gem('foo', '>= 0', true)).to eq '/path/to/foo/doc/.yardoc'
75
+ end
76
+
69
77
  it "returns local .yardoc path for gem if for_writing=true and dir is not writable" do
70
78
  expect(File).to receive(:writable?).with(@gem.doc_dir).and_return(false)
71
79
  expect(File).to receive(:writable?).with(@gem.full_gem_path).and_return(false)
@@ -132,6 +132,7 @@ describe YARD::RegistryStore do
132
132
  Registry.single_object_db = nil
133
133
  add_items(100)
134
134
  saves_to_singledb
135
+ expect(@serializer.complete?).to eq true
135
136
  end
136
137
 
137
138
  it "saves as single object db if single_object_db is nil and there are more than 3000 objects" do
@@ -43,4 +43,35 @@ describe YARD::Serializers::YardocSerializer do
43
43
  @serializer.serialize(data)
44
44
  end
45
45
  end
46
+
47
+ describe "#lock_for_writing" do
48
+ it "creates a lock file during writing and cleans up" do
49
+ expect(File).to receive(:open!).with(@serializer.processing_path, 'w')
50
+ expect(File).to receive(:exist?).with(@serializer.processing_path).exactly(2).times.and_return(true)
51
+ expect(File).to receive(:unlink).with(@serializer.processing_path)
52
+ @serializer.lock_for_writing do
53
+ expect(@serializer.locked_for_writing?).to eq true
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#complete?" do
59
+ it "returns false if complete file does not exist" do
60
+ allow(File).to receive(:exist?).with(@serializer.complete_lock_path).and_return(false)
61
+ allow(File).to receive(:exist?).with(@serializer.processing_path).and_return(false)
62
+ expect(@serializer.complete?).to eq false
63
+ end
64
+
65
+ it "returns false if processing file exists" do
66
+ allow(File).to receive(:exist?).with(@serializer.complete_lock_path).and_return(true)
67
+ allow(File).to receive(:exist?).with(@serializer.processing_path).and_return(true)
68
+ expect(@serializer.complete?).to eq false
69
+ end
70
+
71
+ it "returns true if complete file exists with no processing file" do
72
+ allow(File).to receive(:exist?).with(@serializer.complete_lock_path).and_return(true)
73
+ allow(File).to receive(:exist?).with(@serializer.processing_path).and_return(false)
74
+ expect(@serializer.complete?).to eq true
75
+ end
76
+ end
46
77
  end
@@ -78,6 +78,7 @@ describe YARD::Tags::MacroDirective do
78
78
  :caller_method => 'foo',
79
79
  :scope => :instance, :visibility => :public,
80
80
  :namespace => P('Foo::Bar'),
81
+ :parser => OpenStruct.new(:file => "(stdin)", :line => 1),
81
82
  :statement => OpenStruct.new(:source => 'foo :a, :b, :c'))
82
83
  end
83
84
 
@@ -145,6 +146,15 @@ describe YARD::Tags::MacroDirective do
145
146
  expect(doc).to eq 'expanded_data'
146
147
  end
147
148
 
149
+ it "does not attach macros to class/modules but creates macro" do
150
+ YARD::Registry.clear
151
+ YARD.parse_string "module Foo; end"
152
+ tag_parse("@!macro [attach] attached4\n $1 $2 $3", YARD::Registry.at('Foo'), handler)
153
+ macro = CodeObjects::MacroObject.find('attached4')
154
+ expect(macro.method_object).to eq nil
155
+ expect(log.io.string).to match(/Attaching macros to non-methods is unsupported/)
156
+ end
157
+
148
158
  it "does not attempt to expand macro values if handler = nil" do
149
159
  tag_parse("@!macro [attach] xyz\n $1 $2 $3")
150
160
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Loren Segal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-21 00:00:00.000000000 Z
11
+ date: 2016-07-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  YARD is a documentation generation tool for the Ruby programming language.