yard 0.9.36 → 0.9.38
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 +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +17 -10
- data/docs/Templates.md +5 -4
- data/lib/yard/autoload.rb +1 -0
- data/lib/yard/code_objects/base.rb +1 -1
- data/lib/yard/code_objects/extra_file_object.rb +1 -0
- data/lib/yard/code_objects/macro_object.rb +0 -1
- data/lib/yard/docstring_parser.rb +0 -1
- data/lib/yard/handlers/base.rb +23 -1
- data/lib/yard/handlers/processor.rb +0 -1
- data/lib/yard/handlers/ruby/constant_handler.rb +23 -6
- data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +2 -1
- data/lib/yard/handlers/ruby/visibility_handler.rb +14 -1
- data/lib/yard/logging.rb +116 -61
- data/lib/yard/open_struct.rb +67 -0
- data/lib/yard/parser/ruby/ast_node.rb +5 -4
- data/lib/yard/parser/ruby/legacy/ruby_lex.rb +20 -5
- data/lib/yard/parser/ruby/ruby_parser.rb +54 -21
- data/lib/yard/parser/source_parser.rb +2 -2
- data/lib/yard/tags/default_factory.rb +1 -0
- data/lib/yard/tags/directives.rb +0 -1
- data/lib/yard/tags/overload_tag.rb +2 -1
- data/lib/yard/tags/tag.rb +2 -1
- data/lib/yard/tags/types_explainer.rb +3 -3
- data/lib/yard/templates/engine.rb +0 -1
- data/lib/yard/templates/helpers/html_helper.rb +5 -1
- data/lib/yard/templates/helpers/markup/rdoc_markup.rb +2 -0
- data/lib/yard/templates/template_options.rb +0 -1
- data/lib/yard/version.rb +1 -1
- data/templates/default/fulldoc/html/css/full_list.css +3 -3
- data/templates/default/fulldoc/html/css/style.css +8 -15
- data/templates/default/fulldoc/html/full_list.erb +5 -2
- data/templates/default/fulldoc/html/js/app.js +348 -267
- data/templates/default/fulldoc/html/js/full_list.js +52 -24
- data/templates/default/fulldoc/html/setup.rb +10 -2
- data/templates/default/onefile/html/headers.erb +2 -0
- data/templates/default/tags/html/example.erb +2 -2
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a3a536051e6077e89b4ef2bc4ac2f30e60b8e65d33cdca957fed25644bf901a7
|
|
4
|
+
data.tar.gz: 6f4a7736baaeec0a55e7595b12f5828927fc46115e20e4dd919e96543541cbbd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b9a5348496a1778b2f4a7793df24716329a665fdabbe237932cd126c8309be4543d35b35a279e4ddb3cb31978c1b6e88ae0b799004ee79f2316d6896b9057201
|
|
7
|
+
data.tar.gz: f5c993f3808b9f5baca0c8fc1f92abeb7a113b1be7164dfd71b0b4bff98c58416ea5a82baf473780995d132bbbd7ffbbbffceddb01fda40993fac04bdb790cf8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# main
|
|
2
2
|
|
|
3
|
+
# [0.9.38] - December 5th, 2025
|
|
4
|
+
|
|
5
|
+
[0.9.38]: https://github.com/lsegal/yard/compare/v0.9.37...v0.9.38
|
|
6
|
+
|
|
7
|
+
- Add support for complex constant assignment (#1599)
|
|
8
|
+
- Add support for Data type structs (#1600)
|
|
9
|
+
- Support multi method duck type syntax in type explainer (#1631)
|
|
10
|
+
- Improve Ruby 3.5 compatibility (#1616)
|
|
11
|
+
- Update documentation for various type annotations (#1615)
|
|
12
|
+
- JavaScript frontend updates (resizer, JS bugs, reduce console verbosity) for default template
|
|
13
|
+
- Fix beginless/endless range errors (#1549, #1625)
|
|
14
|
+
- Fix path structure in Templates.md documentation (#1588)
|
|
15
|
+
- Fix signature handling in overload (#1590)
|
|
16
|
+
- Fix handling of **nil with named block (#1623)
|
|
17
|
+
- Fix directives in empty class bodies (#1624)
|
|
18
|
+
- Fix parsing of array within array syntax (#1604)
|
|
19
|
+
- Fix parsing of visibility keywords in front of class methods (#1632)
|
|
20
|
+
|
|
21
|
+
# [0.9.37] - September 4th, 2024
|
|
22
|
+
|
|
23
|
+
[0.9.37]: https://github.com/lsegal/yard/compare/v0.9.36...v0.9.37
|
|
24
|
+
|
|
25
|
+
- Fix JavaScript errors in `--one-file` template (#1426)
|
|
26
|
+
- Fix heredoc parsing and add support for squiggly heredocs (#1315, #1495)
|
|
27
|
+
- Accessibility improvements to the default template (#1501)
|
|
28
|
+
- Improved YARD documentation (#1410, #1512, #1516, #1544)
|
|
29
|
+
- Fix error when parsing `@option` tags (#1515)
|
|
30
|
+
- Fix issue parsing UTF-8 filenames (#1517)
|
|
31
|
+
- Replace OpenStruct with optimized YARD::OpenStruct to avoid ostruct performance warnings (#1545)
|
|
32
|
+
- Add support for `private attr_*` syntax (#1541)
|
|
33
|
+
- Remove logger dependency (#1546)
|
|
34
|
+
|
|
3
35
|
# [0.9.36] - February 29th, 2024
|
|
4
36
|
|
|
5
37
|
[0.9.36]: https://github.com/lsegal/yard/compare/v0.9.35...v0.9.36
|
data/README.md
CHANGED
|
@@ -122,12 +122,19 @@ HTML. If running `which rdoc` turns up empty, install RDoc by issuing:
|
|
|
122
122
|
$ sudo apt-get install rdoc
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
+
### Markdown parser
|
|
126
|
+
|
|
127
|
+
When rendering markdown, yard will use one of several possible markdown providers,
|
|
128
|
+
[in order of priority](https://github.com/lsegal/yard/blob/e833aac7a01510245dd4ae1d1d18b046c8293c2d/lib/yard/templates/helpers/markup_helper.rb#L26-L33).
|
|
129
|
+
If you are experiencing rendering bugs (example [1](https://github.com/lsegal/yard/issues/1410) [2](https://github.com/lsegal/yard/issues/1543)), try adding one of the
|
|
130
|
+
gems further up in the list to your Gemfile.
|
|
131
|
+
|
|
125
132
|
## Usage
|
|
126
133
|
|
|
127
134
|
There are a couple of ways to use YARD. The first is via command-line, and the
|
|
128
135
|
second is the Rake task.
|
|
129
136
|
|
|
130
|
-
|
|
137
|
+
### 1. yard Command-line Tool
|
|
131
138
|
|
|
132
139
|
YARD comes packaged with a executable named `yard` which can control the many
|
|
133
140
|
functions of YARD, including generating documentation, graphs running the YARD
|
|
@@ -140,7 +147,7 @@ $ yard --help
|
|
|
140
147
|
Plugins can also add commands to the `yard` executable to provide extra
|
|
141
148
|
functionality.
|
|
142
149
|
|
|
143
|
-
|
|
150
|
+
#### Generating Documentation
|
|
144
151
|
|
|
145
152
|
<span class="note">The `yardoc` executable is a shortcut for `yard doc`.</span>
|
|
146
153
|
|
|
@@ -185,9 +192,9 @@ Note that the README file can be specified with its own `--readme` switch.
|
|
|
185
192
|
You can also add a `.yardopts` file to your project directory which lists the
|
|
186
193
|
switches separated by whitespace (newlines or space) to pass to yardoc whenever
|
|
187
194
|
it is run. A full overview of the `.yardopts` file can be found in
|
|
188
|
-
|
|
195
|
+
[YARD::CLI::Yardoc](https://rubydoc.info/gems/yard/YARD/CLI/Yardoc#label-Options+File+-28.yardopts-29).
|
|
189
196
|
|
|
190
|
-
|
|
197
|
+
#### Queries
|
|
191
198
|
|
|
192
199
|
The `yardoc` tool also supports a `--query` argument to only include objects
|
|
193
200
|
that match a certain data or meta-data query. The query syntax is Ruby, though a
|
|
@@ -214,7 +221,7 @@ following two lines both check for the existence of a return and param tag:
|
|
|
214
221
|
|
|
215
222
|
For more information about the query syntax, see the {YARD::Verifier} class.
|
|
216
223
|
|
|
217
|
-
|
|
224
|
+
### 2. Rake Task
|
|
218
225
|
|
|
219
226
|
The second most obvious is to generate docs via a Rake task. You can do this by
|
|
220
227
|
adding the following to your `Rakefile`:
|
|
@@ -240,7 +247,7 @@ environment variable:
|
|
|
240
247
|
$ rake yard OPTS='--any --extra --opts'
|
|
241
248
|
```
|
|
242
249
|
|
|
243
|
-
|
|
250
|
+
### 3. `yri` RI Implementation
|
|
244
251
|
|
|
245
252
|
The yri binary will use the cached .yardoc database to give you quick ri-style
|
|
246
253
|
access to your documentation. It's way faster than ri but currently does not
|
|
@@ -264,7 +271,7 @@ $ yard gems
|
|
|
264
271
|
If you don't have sudo access, it will write these files to your `~/.yard`
|
|
265
272
|
directory. `yri` will also cache lookups there.
|
|
266
273
|
|
|
267
|
-
|
|
274
|
+
### 4. `yard server` Documentation Server
|
|
268
275
|
|
|
269
276
|
The `yard server` command serves documentation for a local project or all
|
|
270
277
|
installed RubyGems. To serve documentation for a project you are working on,
|
|
@@ -278,14 +285,14 @@ And the project inside the current directory will be parsed (if the source has
|
|
|
278
285
|
not yet been scanned by YARD) and served at
|
|
279
286
|
[http://localhost:8808](http://localhost:8808).
|
|
280
287
|
|
|
281
|
-
|
|
288
|
+
#### Live Reloading
|
|
282
289
|
|
|
283
290
|
If you want to serve documentation on a project while you document it so that
|
|
284
291
|
you can preview the results, simply pass `--reload` (`-r`) to the above command
|
|
285
292
|
and YARD will reload any changed files on each request. This will allow you to
|
|
286
293
|
change any documentation in the source and refresh to see the new contents.
|
|
287
294
|
|
|
288
|
-
|
|
295
|
+
#### Serving Gems
|
|
289
296
|
|
|
290
297
|
To serve documentation for all installed gems, call:
|
|
291
298
|
|
|
@@ -297,7 +304,7 @@ This will also automatically build documentation for any gems that have not been
|
|
|
297
304
|
previously scanned. Note that in this case there will be a slight delay between
|
|
298
305
|
the first request of a newly parsed gem.
|
|
299
306
|
|
|
300
|
-
|
|
307
|
+
### 5. `yard graph` Graphviz Generator
|
|
301
308
|
|
|
302
309
|
You can use `yard graph` to generate dot graphs of your code. This, of course,
|
|
303
310
|
requires [Graphviz](http://www.graphviz.org) and the `dot` binary. By default
|
data/docs/Templates.md
CHANGED
|
@@ -280,10 +280,11 @@ seen above by creating such a path in our '/path/to/mytemplates' custom template
|
|
|
280
280
|
path:
|
|
281
281
|
|
|
282
282
|
/path/to/mytemplates/:
|
|
283
|
-
|--
|
|
284
|
-
| |--
|
|
285
|
-
| | |--
|
|
286
|
-
| |--
|
|
283
|
+
|--default
|
|
284
|
+
| |-- class
|
|
285
|
+
| | |-- html
|
|
286
|
+
| | | |-- customsection.erb
|
|
287
|
+
| | |-- setup.rb
|
|
287
288
|
|
|
288
289
|
The `setup.rb` file would look like:
|
|
289
290
|
|
data/lib/yard/autoload.rb
CHANGED
|
@@ -298,6 +298,7 @@ module YARD
|
|
|
298
298
|
autoload :DocstringParser, __p('docstring_parser')
|
|
299
299
|
autoload :GemIndex, __p('gem_index')
|
|
300
300
|
autoload :Logger, __p('logging')
|
|
301
|
+
autoload :OpenStruct, __p('open_struct')
|
|
301
302
|
autoload :Options, __p('options')
|
|
302
303
|
autoload :Registry, __p('registry')
|
|
303
304
|
autoload :RegistryResolver, __p('registry_resolver')
|
|
@@ -228,7 +228,7 @@ module YARD
|
|
|
228
228
|
# @example Create class Z inside namespace X::Y
|
|
229
229
|
# CodeObjects::Base.new(P("X::Y"), :Z) # or
|
|
230
230
|
# CodeObjects::Base.new(Registry.root, "X::Y")
|
|
231
|
-
# @param [NamespaceObject] namespace the namespace the object belongs in,
|
|
231
|
+
# @param [NamespaceObject, :root, nil] namespace the namespace the object belongs in,
|
|
232
232
|
# {Registry.root} or :root should be provided if it is associated with
|
|
233
233
|
# the top level namespace.
|
|
234
234
|
# @param [Symbol, String] name the name (or complex path) of the object.
|
data/lib/yard/handlers/base.rb
CHANGED
|
@@ -462,6 +462,18 @@ module YARD
|
|
|
462
462
|
end
|
|
463
463
|
end
|
|
464
464
|
|
|
465
|
+
if docstring.is_a?(String)
|
|
466
|
+
if (m = docstring.match(/^\s*@!?visibility\s+(public|private|protected)\b/m))
|
|
467
|
+
vis_sym = m[1].to_sym
|
|
468
|
+
|
|
469
|
+
if object.nil?
|
|
470
|
+
globals.visibility_origin = :directive
|
|
471
|
+
elsif object.is_a?(CodeObjects::MethodObject)
|
|
472
|
+
object.visibility = vis_sym
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
|
|
465
477
|
register_transitive_tags(object)
|
|
466
478
|
end
|
|
467
479
|
|
|
@@ -511,7 +523,17 @@ module YARD
|
|
|
511
523
|
def register_visibility(object, visibility = self.visibility)
|
|
512
524
|
return unless object.respond_to?(:visibility=)
|
|
513
525
|
return if object.is_a?(NamespaceObject)
|
|
514
|
-
|
|
526
|
+
|
|
527
|
+
if object.is_a?(CodeObjects::MethodObject)
|
|
528
|
+
origin = globals.visibility_origin
|
|
529
|
+
if origin == :keyword
|
|
530
|
+
object.visibility = visibility if object.scope == scope
|
|
531
|
+
else
|
|
532
|
+
object.visibility = visibility
|
|
533
|
+
end
|
|
534
|
+
else
|
|
535
|
+
object.visibility = visibility
|
|
536
|
+
end
|
|
515
537
|
end
|
|
516
538
|
|
|
517
539
|
# Registers the same method information on the module function, if
|
|
@@ -9,6 +9,9 @@ class YARD::Handlers::Ruby::ConstantHandler < YARD::Handlers::Ruby::Base
|
|
|
9
9
|
if statement[1].call? && statement[1][0][0] == s(:const, "Struct") &&
|
|
10
10
|
statement[1][2] == s(:ident, "new")
|
|
11
11
|
process_structclass(statement)
|
|
12
|
+
elsif statement[1].call? && statement[1][0][0] == s(:const, "Data") &&
|
|
13
|
+
statement[1][2] == s(:ident, "define")
|
|
14
|
+
process_dataclass(statement)
|
|
12
15
|
elsif statement[0].type == :var_field && statement[0][0].type == :const
|
|
13
16
|
process_constant(statement)
|
|
14
17
|
elsif statement[0].type == :const_path_field
|
|
@@ -31,20 +34,34 @@ class YARD::Handlers::Ruby::ConstantHandler < YARD::Handlers::Ruby::Base
|
|
|
31
34
|
end
|
|
32
35
|
|
|
33
36
|
def process_structclass(statement)
|
|
34
|
-
lhs = statement[0]
|
|
35
|
-
if lhs.type == :const
|
|
36
|
-
klass = create_class(lhs
|
|
37
|
+
lhs = statement[0]
|
|
38
|
+
if (lhs.type == :var_field && lhs[0].type == :const) || lhs.type == :const_path_field
|
|
39
|
+
klass = create_class(lhs.source, P(:Struct))
|
|
37
40
|
create_attributes(klass, extract_parameters(statement[1]))
|
|
38
41
|
parse_block(statement[1].block[1], :namespace => klass) unless statement[1].block.nil?
|
|
39
42
|
else
|
|
40
|
-
raise YARD::Parser::UndocumentableError, "Struct assignment to #{
|
|
43
|
+
raise YARD::Parser::UndocumentableError, "Struct assignment to #{lhs.source}"
|
|
41
44
|
end
|
|
42
45
|
end
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
def process_dataclass(statement)
|
|
48
|
+
lhs = statement[0]
|
|
49
|
+
if (lhs.type == :var_field && lhs[0].type == :const) || lhs.type == :const_path_field
|
|
50
|
+
klass = create_class(lhs.source, P(:Data))
|
|
51
|
+
extract_parameters(statement[1]).each do |member|
|
|
52
|
+
klass.attributes[:instance][member] = SymbolHash[:read => nil, :write => nil]
|
|
53
|
+
create_reader(klass, member)
|
|
54
|
+
end
|
|
55
|
+
parse_block(statement[1].block[1], :namespace => klass) unless statement[1].block.nil?
|
|
56
|
+
else
|
|
57
|
+
raise YARD::Parser::UndocumentableError, "Data assignment to #{lhs.source}"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Extract the parameters from the Struct.new or Data.define AST node, returning them as a list
|
|
45
62
|
# of strings
|
|
46
63
|
#
|
|
47
|
-
# @param [MethodCallNode] superclass the AST node for the Struct.new call
|
|
64
|
+
# @param [MethodCallNode] superclass the AST node for the Struct.new or Data.define call
|
|
48
65
|
# @return [Array<String>] the member names to generate methods for
|
|
49
66
|
def extract_parameters(superclass)
|
|
50
67
|
return [] unless superclass.parameters
|
|
@@ -8,9 +8,10 @@ class YARD::Handlers::Ruby::Legacy::VisibilityHandler < YARD::Handlers::Ruby::Le
|
|
|
8
8
|
vis = statement.tokens.first.text
|
|
9
9
|
if statement.tokens.size == 1
|
|
10
10
|
self.visibility = vis
|
|
11
|
+
globals.visibility_origin = :keyword
|
|
11
12
|
else
|
|
12
13
|
tokval_list(statement.tokens[2..-1], :attr).each do |name|
|
|
13
|
-
MethodObject.new(namespace, name, scope) {|o| o.visibility = vis }
|
|
14
|
+
MethodObject.new(namespace, name, scope) { |o| o.visibility = vis }
|
|
14
15
|
end
|
|
15
16
|
end
|
|
16
17
|
end
|
|
@@ -13,10 +13,23 @@ class YARD::Handlers::Ruby::VisibilityHandler < YARD::Handlers::Ruby::Base
|
|
|
13
13
|
case statement.type
|
|
14
14
|
when :var_ref, :vcall
|
|
15
15
|
self.visibility = ident.first.to_sym
|
|
16
|
-
|
|
16
|
+
globals.visibility_origin = :keyword
|
|
17
|
+
when :command
|
|
18
|
+
if RUBY_VERSION >= '3.' && is_attribute_method?(statement.parameters.first)
|
|
19
|
+
parse_block(statement.parameters.first, visibility: ident.first.to_sym)
|
|
20
|
+
return
|
|
21
|
+
end
|
|
22
|
+
process_decorator do |method|
|
|
23
|
+
method.visibility = ident.first if method.respond_to? :visibility=
|
|
24
|
+
end
|
|
25
|
+
when :fcall
|
|
17
26
|
process_decorator do |method|
|
|
18
27
|
method.visibility = ident.first if method.respond_to? :visibility=
|
|
19
28
|
end
|
|
20
29
|
end
|
|
21
30
|
end
|
|
31
|
+
|
|
32
|
+
def is_attribute_method?(node)
|
|
33
|
+
node.type == :command && node.jump(:ident).first.to_s =~ /^attr_(accessor|writer|reader)$/
|
|
34
|
+
end
|
|
22
35
|
end
|
data/lib/yard/logging.rb
CHANGED
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
-
require 'logger'
|
|
4
3
|
require 'thread'
|
|
5
4
|
|
|
6
5
|
module YARD
|
|
7
6
|
# Handles console logging for info, warnings and errors.
|
|
8
7
|
# Uses the stdlib Logger class in Ruby for all the backend logic.
|
|
9
|
-
class Logger
|
|
8
|
+
class Logger
|
|
9
|
+
# Log severity levels
|
|
10
|
+
module Severity
|
|
11
|
+
# Debugging log level
|
|
12
|
+
DEBUG = 0
|
|
13
|
+
|
|
14
|
+
# Information log level
|
|
15
|
+
INFO = 1
|
|
16
|
+
|
|
17
|
+
# Warning log level
|
|
18
|
+
WARN = 2
|
|
19
|
+
|
|
20
|
+
# Error log level
|
|
21
|
+
ERROR = 3
|
|
22
|
+
|
|
23
|
+
# Fatal log level
|
|
24
|
+
FATAL = 4
|
|
25
|
+
|
|
26
|
+
# Unknown log level
|
|
27
|
+
UNKNOWN = 5
|
|
28
|
+
|
|
29
|
+
# @private
|
|
30
|
+
SEVERITIES = {
|
|
31
|
+
DEBUG => :debug,
|
|
32
|
+
INFO => :info,
|
|
33
|
+
WARN => :warn,
|
|
34
|
+
ERROR => :error,
|
|
35
|
+
FATAL => :fatal,
|
|
36
|
+
UNKNOWN => :unknown
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
include Severity
|
|
41
|
+
|
|
10
42
|
# The list of characters displayed beside the progress bar to indicate
|
|
11
43
|
# "movement".
|
|
12
44
|
# @since 0.8.2
|
|
@@ -14,25 +46,31 @@ module YARD
|
|
|
14
46
|
|
|
15
47
|
# @return [IO] the IO object being logged to
|
|
16
48
|
# @since 0.8.2
|
|
17
|
-
|
|
18
|
-
def io=(pipe) @logdev = pipe end
|
|
49
|
+
attr_accessor :io
|
|
19
50
|
|
|
20
51
|
# @return [Boolean] whether backtraces should be shown (by default
|
|
21
52
|
# this is on).
|
|
22
53
|
def show_backtraces; @show_backtraces || level == DEBUG end
|
|
23
54
|
attr_writer :show_backtraces
|
|
24
55
|
|
|
56
|
+
# @return [DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN] the logging level
|
|
57
|
+
attr_accessor :level
|
|
58
|
+
|
|
59
|
+
# @return [Boolean] whether a warn message has been emitted. Used for status tracking.
|
|
60
|
+
attr_accessor :warned
|
|
61
|
+
|
|
25
62
|
# @return [Boolean] whether progress indicators should be shown when
|
|
26
63
|
# logging CLIs (by default this is off).
|
|
27
64
|
def show_progress
|
|
28
65
|
return false if YARD.ruby18? # threading is too ineffective for progress support
|
|
29
|
-
return false if YARD.windows? # windows has poor ANSI support
|
|
30
66
|
return false unless io.tty? # no TTY support on IO
|
|
31
67
|
return false unless level > INFO # no progress in verbose/debug modes
|
|
32
68
|
@show_progress
|
|
33
69
|
end
|
|
34
70
|
attr_writer :show_progress
|
|
35
71
|
|
|
72
|
+
# @!group Constructor Methods
|
|
73
|
+
|
|
36
74
|
# The logger instance
|
|
37
75
|
# @return [Logger] the logger instance
|
|
38
76
|
def self.instance(pipe = STDOUT)
|
|
@@ -40,13 +78,12 @@ module YARD
|
|
|
40
78
|
end
|
|
41
79
|
|
|
42
80
|
# Creates a new logger
|
|
81
|
+
# @private
|
|
43
82
|
def initialize(pipe, *args)
|
|
44
|
-
super(pipe, *args)
|
|
45
83
|
self.io = pipe
|
|
46
84
|
self.show_backtraces = true
|
|
47
85
|
self.show_progress = false
|
|
48
86
|
self.level = WARN
|
|
49
|
-
self.formatter = method(:format_log)
|
|
50
87
|
self.warned = false
|
|
51
88
|
@progress_indicator = 0
|
|
52
89
|
@mutex = Mutex.new
|
|
@@ -54,36 +91,64 @@ module YARD
|
|
|
54
91
|
@progress_last_update = Time.now
|
|
55
92
|
end
|
|
56
93
|
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
94
|
+
# @!macro [attach] logger.create_log_method
|
|
95
|
+
# @method $1(message)
|
|
96
|
+
# Logs a message with the $1 severity level.
|
|
97
|
+
# @param message [String] the message to log
|
|
98
|
+
# @see #log
|
|
99
|
+
# @return [void]
|
|
100
|
+
# @private
|
|
101
|
+
def self.create_log_method(name)
|
|
102
|
+
severity = Severity.const_get(name.to_s.upcase)
|
|
103
|
+
define_method(name) { |message| log(severity, message) }
|
|
62
104
|
end
|
|
63
105
|
|
|
106
|
+
# @!group Logging Methods
|
|
107
|
+
|
|
108
|
+
create_log_method :info
|
|
109
|
+
create_log_method :error
|
|
110
|
+
create_log_method :fatal
|
|
111
|
+
create_log_method :unknown
|
|
112
|
+
|
|
113
|
+
# Changes the debug level to DEBUG if $DEBUG is set and writes a debugging message.
|
|
114
|
+
create_log_method :debug
|
|
115
|
+
|
|
64
116
|
# Remembers when a warning occurs and writes a warning message.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
117
|
+
create_log_method :warn
|
|
118
|
+
|
|
119
|
+
# Logs a message with a given severity
|
|
120
|
+
# @param severity [DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN] the severity level
|
|
121
|
+
# @param message [String] the message to log
|
|
122
|
+
def log(severity, message)
|
|
123
|
+
self.level = DEBUG if $DEBUG
|
|
124
|
+
return unless severity >= level
|
|
125
|
+
|
|
126
|
+
self.warned = true if severity == WARN
|
|
127
|
+
clear_line
|
|
128
|
+
puts "[#{SEVERITIES[severity].to_s.downcase}]: #{message}"
|
|
68
129
|
end
|
|
69
|
-
attr_accessor :warned
|
|
70
130
|
|
|
71
|
-
#
|
|
72
|
-
|
|
131
|
+
# @!group Level Control Methods
|
|
132
|
+
|
|
133
|
+
# Sets the logger level for the duration of the block
|
|
73
134
|
#
|
|
74
|
-
# @
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
# @
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
135
|
+
# @example
|
|
136
|
+
# log.enter_level(Logger::ERROR) do
|
|
137
|
+
# YARD.parse_string "def x; end"
|
|
138
|
+
# end
|
|
139
|
+
# @param [Fixnum] new_level the logger level for the duration of the block.
|
|
140
|
+
# values can be found in Ruby's Logger class.
|
|
141
|
+
# @yield the block with the logger temporarily set to +new_level+
|
|
142
|
+
def enter_level(new_level = level)
|
|
143
|
+
old_level = level
|
|
144
|
+
self.level = new_level
|
|
82
145
|
yield
|
|
83
146
|
ensure
|
|
84
|
-
|
|
147
|
+
self.level = old_level
|
|
85
148
|
end
|
|
86
149
|
|
|
150
|
+
# @!group Utility Printing Methods
|
|
151
|
+
|
|
87
152
|
# Displays a progress indicator for a given message. This progress report
|
|
88
153
|
# is only displayed on TTY displays, otherwise the message is passed to
|
|
89
154
|
# the +nontty_log+ level.
|
|
@@ -120,7 +185,7 @@ module YARD
|
|
|
120
185
|
# @since 0.8.2
|
|
121
186
|
def clear_progress
|
|
122
187
|
return unless show_progress
|
|
123
|
-
|
|
188
|
+
io.write("\e[?25h\e[2K")
|
|
124
189
|
@progress_msg = nil
|
|
125
190
|
end
|
|
126
191
|
|
|
@@ -133,16 +198,13 @@ module YARD
|
|
|
133
198
|
print("#{msg}\n")
|
|
134
199
|
end
|
|
135
200
|
|
|
136
|
-
alias print_no_newline <<
|
|
137
|
-
private :print_no_newline
|
|
138
|
-
|
|
139
201
|
# Displays an unformatted line to the logger output stream.
|
|
140
202
|
# @param [String] msg the message to display
|
|
141
203
|
# @return [void]
|
|
142
204
|
# @since 0.8.2
|
|
143
205
|
def print(msg = '')
|
|
144
206
|
clear_line
|
|
145
|
-
|
|
207
|
+
io.write(msg)
|
|
146
208
|
end
|
|
147
209
|
alias << print
|
|
148
210
|
|
|
@@ -158,48 +220,41 @@ module YARD
|
|
|
158
220
|
exc.backtrace[0..5].map {|x| "\n\t#{x}" }.join + "\n")
|
|
159
221
|
end
|
|
160
222
|
|
|
223
|
+
# @!group Benchmarking Methods
|
|
224
|
+
|
|
225
|
+
# Captures the duration of a block of code for benchmark analysis. Also
|
|
226
|
+
# calls {#progress} on the message to display it to the user.
|
|
227
|
+
#
|
|
228
|
+
# @todo Implement capture storage for reporting of benchmarks
|
|
229
|
+
# @param [String] msg the message to display
|
|
230
|
+
# @param [Symbol, nil] nontty_log the level to log as if the output
|
|
231
|
+
# stream is not a TTY. Use +nil+ for no alternate logging.
|
|
232
|
+
# @yield a block of arbitrary code to benchmark
|
|
233
|
+
# @return [void]
|
|
234
|
+
def capture(msg, nontty_log = :debug)
|
|
235
|
+
progress(msg, nontty_log)
|
|
236
|
+
yield
|
|
237
|
+
ensure
|
|
238
|
+
clear_progress
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# @!endgroup
|
|
242
|
+
|
|
161
243
|
# Warns that the Ruby environment does not support continuations. Applies
|
|
162
244
|
# to JRuby, Rubinius and MacRuby. This warning will only display once
|
|
163
245
|
# per Ruby process.
|
|
164
246
|
#
|
|
165
247
|
# @deprecated Continuations are no longer needed by YARD 0.8.0+.
|
|
166
248
|
# @return [void]
|
|
249
|
+
# @private
|
|
167
250
|
def warn_no_continuations
|
|
168
251
|
end
|
|
169
252
|
|
|
170
|
-
# Sets the logger level for the duration of the block
|
|
171
|
-
#
|
|
172
|
-
# @example
|
|
173
|
-
# log.enter_level(Logger::ERROR) do
|
|
174
|
-
# YARD.parse_string "def x; end"
|
|
175
|
-
# end
|
|
176
|
-
# @param [Fixnum] new_level the logger level for the duration of the block.
|
|
177
|
-
# values can be found in Ruby's Logger class.
|
|
178
|
-
# @yield the block with the logger temporarily set to +new_level+
|
|
179
|
-
def enter_level(new_level = level)
|
|
180
|
-
old_level = level
|
|
181
|
-
self.level = new_level
|
|
182
|
-
yield
|
|
183
|
-
ensure
|
|
184
|
-
self.level = old_level
|
|
185
|
-
end
|
|
186
|
-
|
|
187
253
|
private
|
|
188
254
|
|
|
189
|
-
# Override this internal Logger method to clear line
|
|
190
|
-
def add(*args)
|
|
191
|
-
clear_line
|
|
192
|
-
super(*args)
|
|
193
|
-
end
|
|
194
|
-
|
|
195
255
|
def clear_line
|
|
196
256
|
return unless @progress_msg
|
|
197
|
-
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
# Log format (from Logger implementation). Used by Logger internally
|
|
201
|
-
def format_log(sev, _time, _prog, msg)
|
|
202
|
-
"[#{sev.downcase}]: #{msg}\n"
|
|
257
|
+
io.write("\e[2K\r")
|
|
203
258
|
end
|
|
204
259
|
end
|
|
205
260
|
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module YARD
|
|
2
|
+
# An OpenStruct compatible struct class that allows for basic access of attributes
|
|
3
|
+
# via +struct.attr_name+ and +struct.attr_name = value+.
|
|
4
|
+
class OpenStruct
|
|
5
|
+
def initialize(hash = {})
|
|
6
|
+
@table = hash.each_pair { |k, v| [k.to_sym, v] }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# @private
|
|
10
|
+
def method_missing(name, *args)
|
|
11
|
+
if name.to_s.end_with?('=')
|
|
12
|
+
varname = name.to_s[0..-2].to_sym
|
|
13
|
+
__cache_lookup__(varname)
|
|
14
|
+
send(name, args.first)
|
|
15
|
+
else
|
|
16
|
+
__cache_lookup__(name)
|
|
17
|
+
send(name)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_h
|
|
22
|
+
@table.dup
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def ==(other)
|
|
26
|
+
other.is_a?(self.class) && to_h == other.to_h
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def hash
|
|
30
|
+
@table.hash
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def dig(*keys)
|
|
34
|
+
@table.dig(*keys)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def []=(key, value)
|
|
38
|
+
@table[key.to_sym] = value
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def [](key)
|
|
42
|
+
@table[key.to_sym]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def each_pair(&block)
|
|
46
|
+
@table.each_pair(&block)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def marshal_dump
|
|
50
|
+
@table
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def marshal_load(data)
|
|
54
|
+
@table = data
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def __cache_lookup__(name)
|
|
60
|
+
key = name.to_sym.inspect
|
|
61
|
+
instance_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
62
|
+
def #{name}; @table[#{key}]; end
|
|
63
|
+
def #{name.to_s.sub('?','_')}=(v); @table[#{key}] = v; end unless #{key}.to_s.include?('?')
|
|
64
|
+
RUBY
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|