yard 0.8.1 → 0.8.2
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.
- data/ChangeLog +192 -0
- data/README.md +9 -2
- data/Rakefile +8 -14
- data/lib/yard.rb +1 -1
- data/lib/yard/autoload.rb +3 -2
- data/lib/yard/cli/graph.rb +28 -10
- data/lib/yard/cli/yardoc.rb +4 -1
- data/lib/yard/code_objects/proxy.rb +22 -17
- data/lib/yard/docstring_parser.rb +7 -7
- data/lib/yard/globals.rb +2 -2
- data/lib/yard/handlers/base.rb +3 -2
- data/lib/yard/handlers/c/handler_methods.rb +1 -0
- data/lib/yard/handlers/c/init_handler.rb +7 -5
- data/lib/yard/handlers/c/override_comment_handler.rb +9 -1
- data/lib/yard/handlers/ruby/class_condition_handler.rb +4 -2
- data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +4 -2
- data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +4 -6
- data/lib/yard/handlers/ruby/mixin_handler.rb +3 -3
- data/lib/yard/handlers/ruby/visibility_handler.rb +1 -1
- data/lib/yard/i18n/locale.rb +50 -0
- data/lib/yard/i18n/text.rb +110 -9
- data/lib/yard/logging.rb +99 -8
- data/lib/yard/parser/c/c_parser.rb +1 -1
- data/lib/yard/parser/source_parser.rb +5 -4
- data/lib/yard/registry.rb +20 -12
- data/lib/yard/registry_store.rb +6 -1
- data/lib/yard/rubygems/doc_manager.rb +9 -5
- data/lib/yard/serializers/yardoc_serializer.rb +1 -0
- data/lib/yard/server/commands/base.rb +3 -2
- data/lib/yard/server/doc_server_serializer.rb +2 -0
- data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -0
- data/lib/yard/server/templates/default/method_details/html/setup.rb +4 -0
- data/lib/yard/tags/default_factory.rb +12 -4
- data/lib/yard/tags/directives.rb +1 -0
- data/lib/yard/templates/engine.rb +13 -6
- data/lib/yard/templates/template_options.rb +8 -1
- data/spec/cli/graph_spec.rb +10 -0
- data/spec/cli/yri_spec.rb +12 -2
- data/spec/code_objects/proxy_spec.rb +19 -3
- data/spec/handlers/c/class_handler_spec.rb +1 -2
- data/spec/handlers/c/init_handler_spec.rb +11 -0
- data/spec/handlers/c/override_comment_handler_spec.rb +3 -0
- data/spec/handlers/class_condition_handler_spec.rb +5 -0
- data/spec/handlers/dsl_handler_spec.rb +1 -0
- data/spec/handlers/examples/class_condition_handler_001.rb.txt +8 -0
- data/spec/handlers/mixin_handler_spec.rb +2 -1
- data/spec/i18n/locale_spec.rb +62 -0
- data/spec/i18n/text_spec.rb +144 -35
- data/spec/logging_spec.rb +21 -0
- data/spec/parser/c_parser_spec.rb +36 -0
- data/spec/parser/source_parser_spec.rb +11 -8
- data/spec/registry_spec.rb +26 -0
- data/spec/rubygems/doc_manager_spec.rb +112 -0
- data/spec/tags/default_factory_spec.rb +8 -2
- data/spec/tags/directives_spec.rb +7 -0
- data/spec/templates/examples/module001.html +0 -4
- data/spec/templates/examples/module002.html +0 -1
- data/spec/templates/examples/module003.html +0 -1
- data/spec/templates/examples/module004.html +171 -172
- data/spec/templates/module_spec.rb +4 -0
- data/templates/default/fulldoc/html/js/app.js +24 -18
- data/templates/default/fulldoc/html/setup.rb +5 -1
- data/templates/default/module/html/attribute_details.erb +1 -2
- metadata +9 -4
- data/lib/yard/server/templates/default/fulldoc/html/js/live.js +0 -17
@@ -29,25 +29,25 @@ module YARD
|
|
29
29
|
class DocstringParser
|
30
30
|
# @return [String] the parsed text portion of the docstring,
|
31
31
|
# with tags removed.
|
32
|
-
|
32
|
+
attr_accessor :text
|
33
33
|
|
34
34
|
# @return [String] the complete input string to the parser.
|
35
|
-
|
35
|
+
attr_accessor :raw_text
|
36
36
|
|
37
37
|
# @return [Array<Tag>] the list of meta-data tags identified
|
38
38
|
# by the parser
|
39
|
-
|
39
|
+
attr_accessor :tags
|
40
40
|
|
41
41
|
# @return [Array<Directive>] a list of directives identified
|
42
42
|
# by the parser. This list will not be passed on to the
|
43
43
|
# Docstring object.
|
44
|
-
|
44
|
+
attr_accessor :directives
|
45
45
|
|
46
46
|
# @return [OpenStruct] any arbitrary state to be passed between
|
47
47
|
# tags during parsing. Mainly used by directives to coordinate
|
48
48
|
# behaviour (so that directives can be aware of other directives
|
49
49
|
# used in a docstring).
|
50
|
-
|
50
|
+
attr_accessor :state
|
51
51
|
|
52
52
|
# @return [CodeObjects::Base, nil] the object associated with
|
53
53
|
# the docstring being parsed. May be nil if the docstring is
|
@@ -177,7 +177,7 @@ module YARD
|
|
177
177
|
|
178
178
|
# Creates a tag from the {Tags::DefaultFactory tag factory}.
|
179
179
|
#
|
180
|
-
# To add an already created tag object,
|
180
|
+
# To add an already created tag object, append it to {#tags}.
|
181
181
|
#
|
182
182
|
# @param [String] tag_name the tag name
|
183
183
|
# @param [String] tag_buf the text attached to the tag with newlines removed.
|
@@ -264,7 +264,7 @@ module YARD
|
|
264
264
|
self.after_parse_callbacks << block
|
265
265
|
end
|
266
266
|
|
267
|
-
# @return [Array<Proc>] the {
|
267
|
+
# @return [Array<Proc>] the {after_parse} callback proc objects
|
268
268
|
def self.after_parse_callbacks
|
269
269
|
@after_parse_callbacks ||= []
|
270
270
|
end
|
data/lib/yard/globals.rb
CHANGED
@@ -4,9 +4,9 @@
|
|
4
4
|
#
|
5
5
|
# @see YARD::CodeObjects::Proxy
|
6
6
|
# @see YARD::Registry.resolve
|
7
|
-
def P(namespace, name = nil)
|
7
|
+
def P(namespace, name = nil, type = nil)
|
8
8
|
namespace, name = nil, namespace if name.nil?
|
9
|
-
YARD::Registry.resolve(namespace, name, false, true)
|
9
|
+
YARD::Registry.resolve(namespace, name, false, true, type)
|
10
10
|
end
|
11
11
|
|
12
12
|
# The global {YARD::Logger} instance
|
data/lib/yard/handlers/base.rb
CHANGED
@@ -356,12 +356,13 @@ module YARD
|
|
356
356
|
opts = {
|
357
357
|
:namespace => namespace,
|
358
358
|
:scope => :instance,
|
359
|
-
:owner => owner || namespace
|
359
|
+
:owner => owner || namespace,
|
360
|
+
:visibility => nil
|
360
361
|
}.update(opts)
|
361
362
|
|
362
363
|
ns, vis, sc, oo = namespace, visibility, scope, owner
|
363
364
|
self.namespace = opts[:namespace]
|
364
|
-
self.visibility = :public
|
365
|
+
self.visibility = opts[:visibility] || :public
|
365
366
|
self.scope = opts[:scope]
|
366
367
|
self.owner = opts[:owner]
|
367
368
|
|
@@ -61,6 +61,7 @@ module YARD
|
|
61
61
|
|
62
62
|
def handle_alias(var_name, new_name, old_name)
|
63
63
|
namespace = namespace_for_variable(var_name)
|
64
|
+
return if namespace.nil?
|
64
65
|
new_meth, old_meth = new_name.to_sym, old_name.to_sym
|
65
66
|
old_obj = namespace.child(:name => old_meth, :scope => :instance)
|
66
67
|
new_obj = register MethodObject.new(namespace, new_meth, :instance) do |o|
|
@@ -1,15 +1,17 @@
|
|
1
1
|
# Handles the Init_Libname() method
|
2
2
|
class YARD::Handlers::C::InitHandler < YARD::Handlers::C::Base
|
3
|
-
MATCH = %r{\A\s*(?:static\s+)?void\s+[Ii]nit_(\w+)\s*}
|
3
|
+
MATCH = %r{\A\s*(?:static\s+)?void\s+(?:[Ii]nit_)?(\w+)\s*}
|
4
4
|
handles MATCH
|
5
5
|
statement_class ToplevelStatement
|
6
6
|
|
7
7
|
process do
|
8
8
|
parse_block
|
9
|
-
|
10
|
-
|
11
|
-
if
|
12
|
-
|
9
|
+
if decl = statement.declaration[MATCH, 1]
|
10
|
+
ns = namespace_for_variable(decl)
|
11
|
+
if ns.is_a?(YARD::CodeObjects::NamespaceObject) && ns.docstring.blank?
|
12
|
+
if statement.comments
|
13
|
+
register_docstring(ns, statement.comments.source, statement)
|
14
|
+
end
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -16,7 +16,15 @@ class YARD::Handlers::C::OverrideCommentHandler < YARD::Handlers::C::Base
|
|
16
16
|
when :module
|
17
17
|
obj = YARD::CodeObjects::ModuleObject.new(:root, name)
|
18
18
|
end
|
19
|
-
|
19
|
+
register(obj)
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
def register_docstring(object, docstring = statement.source, stmt = statement)
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def register_file_info(object, file = parser.file, line = statement.line, comments = statement.comments)
|
28
|
+
super
|
29
|
+
end
|
22
30
|
end
|
@@ -75,10 +75,12 @@ class YARD::Handlers::Ruby::ClassConditionHandler < YARD::Handlers::Ruby::Base
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def parse_then_block
|
78
|
-
parse_block(statement.then_block)
|
78
|
+
parse_block(statement.then_block, :visibility => visibility)
|
79
79
|
end
|
80
80
|
|
81
81
|
def parse_else_block
|
82
|
-
|
82
|
+
if statement.else_block
|
83
|
+
parse_block(statement.else_block, :visibility => visibility)
|
84
|
+
end
|
83
85
|
end
|
84
86
|
end
|
@@ -65,7 +65,7 @@ class YARD::Handlers::Ruby::Legacy::ClassConditionHandler < YARD::Handlers::Ruby
|
|
65
65
|
|
66
66
|
# @since 0.5.5
|
67
67
|
def parse_then_block
|
68
|
-
parse_block
|
68
|
+
parse_block(:visibility => visibility)
|
69
69
|
end
|
70
70
|
|
71
71
|
# @since 0.5.5
|
@@ -74,7 +74,9 @@ class YARD::Handlers::Ruby::Legacy::ClassConditionHandler < YARD::Handlers::Ruby
|
|
74
74
|
stmtlist = YARD::Parser::Ruby::Legacy::StatementList
|
75
75
|
stmtlist.new(statement.block).each do |stmt|
|
76
76
|
if TkELSE === stmt.tokens.first
|
77
|
-
|
77
|
+
push_state(:visibility => visibility) do
|
78
|
+
parser.process(stmtlist.new(stmt.block))
|
79
|
+
end
|
78
80
|
end
|
79
81
|
end
|
80
82
|
end
|
@@ -27,13 +27,11 @@ class YARD::Handlers::Ruby::Legacy::MixinHandler < YARD::Handlers::Ruby::Legacy:
|
|
27
27
|
raise YARD::Parser::UndocumentableError
|
28
28
|
end
|
29
29
|
|
30
|
-
obj = Proxy.new(namespace, mixmatch)
|
31
|
-
|
32
|
-
case obj
|
33
|
-
when Proxy
|
34
|
-
obj.type = :module
|
30
|
+
case obj = Proxy.new(namespace, mixmatch)
|
35
31
|
when ConstantObject # If a constant is included, use its value as the real object
|
36
|
-
obj = Proxy.new(namespace, obj.value)
|
32
|
+
obj = Proxy.new(namespace, obj.value, :module)
|
33
|
+
else
|
34
|
+
obj = Proxy.new(namespace, mixmatch, :module)
|
37
35
|
end
|
38
36
|
|
39
37
|
namespace.mixins(scope).unshift(obj) unless namespace.mixins(scope).include?(obj)
|
@@ -25,10 +25,10 @@ class YARD::Handlers::Ruby::MixinHandler < YARD::Handlers::Ruby::Base
|
|
25
25
|
raise YARD::Parser::UndocumentableError if mixin.first.type == :ident
|
26
26
|
|
27
27
|
case obj = Proxy.new(namespace, mixin.source)
|
28
|
-
when Proxy
|
29
|
-
obj.type = :module
|
30
28
|
when ConstantObject # If a constant is included, use its value as the real object
|
31
|
-
obj = Proxy.new(namespace, obj.value)
|
29
|
+
obj = Proxy.new(namespace, obj.value, :module)
|
30
|
+
else
|
31
|
+
obj = Proxy.new(namespace, mixin.source, :module)
|
32
32
|
end
|
33
33
|
|
34
34
|
namespace.mixins(scope).unshift(obj) unless namespace.mixins(scope).include?(obj)
|
@@ -9,7 +9,7 @@ class YARD::Handlers::Ruby::VisibilityHandler < YARD::Handlers::Ruby::Base
|
|
9
9
|
return if (ident = statement.jump(:ident)) == statement
|
10
10
|
case statement.type
|
11
11
|
when :var_ref, :vcall
|
12
|
-
self.visibility = ident.first
|
12
|
+
self.visibility = ident.first.to_sym
|
13
13
|
when :fcall, :command
|
14
14
|
statement[1].traverse do |node|
|
15
15
|
case node.type
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "gettext/tools/poparser"
|
2
|
+
require "gettext/runtime/mofile"
|
3
|
+
|
4
|
+
module YARD
|
5
|
+
module I18n
|
6
|
+
# +Locale+ is a unit of translation. It has {#name} and a set of
|
7
|
+
# messages.
|
8
|
+
#
|
9
|
+
# @since 0.8.2
|
10
|
+
class Locale
|
11
|
+
# @return [String] the name of the locale. It used IETF language
|
12
|
+
# tag format +[language[_territory][.codeset][@modifier]]+.
|
13
|
+
# @see http://tools.ietf.org/rfc/bcp/bcp47.txt
|
14
|
+
# BCP 47 - Tags for Identifying Languages
|
15
|
+
attr_reader :name
|
16
|
+
|
17
|
+
# Creates a locale for +name+ locale.
|
18
|
+
#
|
19
|
+
# @param [String] name the locale name.
|
20
|
+
def initialize(name)
|
21
|
+
@name = name
|
22
|
+
@messages = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
# Loads translation messages from +locale_directory+/{#name}.po.
|
26
|
+
#
|
27
|
+
# @param [String] locale_directory the directory path that has
|
28
|
+
# {#name}.po.
|
29
|
+
# @return [Boolean] +true+ if PO file exists, +false+ otherwise.
|
30
|
+
def load(locale_directory)
|
31
|
+
po_file = File.join(locale_directory, "#{@name}.po")
|
32
|
+
return false unless File.exist?(po_file)
|
33
|
+
|
34
|
+
parser = GetText::PoParser.new
|
35
|
+
parser.report_warning = false
|
36
|
+
data = GetText::MoFile.new
|
37
|
+
parser.parse_file(po_file, data)
|
38
|
+
@messages.merge!(data)
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param [String] message the translation target message.
|
43
|
+
# @return [String] translated message. If tarnslation isn't
|
44
|
+
# registered, the +message+ is returned.
|
45
|
+
def translate(message)
|
46
|
+
@messages[message] || message
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/yard/i18n/text.rb
CHANGED
@@ -32,6 +32,48 @@ module YARD
|
|
32
32
|
# extracted paragraph.
|
33
33
|
# @return [void]
|
34
34
|
def extract_messages
|
35
|
+
parse do |part|
|
36
|
+
line_no = part[:line_no]
|
37
|
+
case part[:type]
|
38
|
+
when :markup, :empty_line
|
39
|
+
# ignore
|
40
|
+
when :attribute
|
41
|
+
yield(:attribute, part[:name], part[:value], part[:line_no])
|
42
|
+
when :paragraph
|
43
|
+
yield(:paragraph, part[:paragraph], part[:line_no])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Translates into +locale+.
|
49
|
+
#
|
50
|
+
# @param [Locale] locale the translation target locale.
|
51
|
+
# @return [String] translated text.
|
52
|
+
def translate(locale)
|
53
|
+
translated_text = ""
|
54
|
+
parse do |part|
|
55
|
+
case part[:type]
|
56
|
+
when :markup
|
57
|
+
translated_text << part[:line]
|
58
|
+
when :attribute
|
59
|
+
prefix = "#{part[:prefix]}#{part[:name]}#{part[:infix]}"
|
60
|
+
value = locale.translate(part[:value])
|
61
|
+
suffix = part[:suffix]
|
62
|
+
translated_text << "#{prefix}#{value}#{suffix}"
|
63
|
+
when :paragraph
|
64
|
+
translated_text << locale.translate(part[:paragraph])
|
65
|
+
when :empty_line
|
66
|
+
translated_text << part[:line]
|
67
|
+
else
|
68
|
+
raise "should not reach here: unexpected type: #{type}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
translated_text
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def parse(&block)
|
35
77
|
paragraph = ""
|
36
78
|
paragraph_start_line = 0
|
37
79
|
line_no = 0
|
@@ -42,29 +84,88 @@ module YARD
|
|
42
84
|
if in_header
|
43
85
|
case line
|
44
86
|
when /^#!\S+\s*$/
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
87
|
+
if line_no == 1
|
88
|
+
emit_markup_event(line, line_no, &block)
|
89
|
+
else
|
90
|
+
in_header = false
|
91
|
+
end
|
92
|
+
when /^(\s*#\s*@)(\S+)(\s*)(.+?)(\s*)$/
|
93
|
+
emit_attribute_event(Regexp.last_match, line_no, &block)
|
49
94
|
else
|
50
95
|
in_header = false
|
51
|
-
|
96
|
+
if line.strip.empty?
|
97
|
+
emit_empty_line_event(line, line_no, &block)
|
98
|
+
next
|
99
|
+
end
|
52
100
|
end
|
53
101
|
next if in_header
|
54
102
|
end
|
55
103
|
|
56
104
|
case line
|
57
105
|
when /^\s*$/
|
58
|
-
|
59
|
-
|
60
|
-
|
106
|
+
if paragraph.empty?
|
107
|
+
emit_empty_line_event(line, line_no, &block)
|
108
|
+
else
|
109
|
+
paragraph << line
|
110
|
+
emit_paragraph_event(paragraph, paragraph_start_line, line_no,
|
111
|
+
&block)
|
112
|
+
paragraph = ""
|
113
|
+
end
|
61
114
|
else
|
62
115
|
paragraph_start_line = line_no if paragraph.empty?
|
63
116
|
paragraph << line
|
64
117
|
end
|
65
118
|
end
|
119
|
+
|
66
120
|
unless paragraph.empty?
|
67
|
-
|
121
|
+
emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def emit_markup_event(line, line_no)
|
126
|
+
part = {
|
127
|
+
:type => :markup,
|
128
|
+
:line => line,
|
129
|
+
:line_no => line_no,
|
130
|
+
}
|
131
|
+
yield(part)
|
132
|
+
end
|
133
|
+
|
134
|
+
def emit_attribute_event(match_data, line_no)
|
135
|
+
part = {
|
136
|
+
:type => :attribute,
|
137
|
+
:prefix => match_data[1],
|
138
|
+
:name => match_data[2],
|
139
|
+
:infix => match_data[3],
|
140
|
+
:value => match_data[4],
|
141
|
+
:suffix => match_data[5],
|
142
|
+
:line_no => line_no,
|
143
|
+
}
|
144
|
+
yield(part)
|
145
|
+
end
|
146
|
+
|
147
|
+
def emit_empty_line_event(line, line_no)
|
148
|
+
part = {
|
149
|
+
:type => :empty_line,
|
150
|
+
:line => line,
|
151
|
+
:line_no => line_no,
|
152
|
+
}
|
153
|
+
yield(part)
|
154
|
+
end
|
155
|
+
|
156
|
+
def emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block)
|
157
|
+
paragraph_part = {
|
158
|
+
:type => :paragraph,
|
159
|
+
:line_no => paragraph_start_line,
|
160
|
+
}
|
161
|
+
match_data = /(\s*)\z/.match(paragraph)
|
162
|
+
if match_data
|
163
|
+
paragraph_part[:paragraph] = match_data.pre_match
|
164
|
+
yield(paragraph_part)
|
165
|
+
emit_empty_line_event(match_data[1], line_no, &block)
|
166
|
+
else
|
167
|
+
paragraph_part[:paragraph] = paragraph
|
168
|
+
yield(paragraph_part)
|
68
169
|
end
|
69
170
|
end
|
70
171
|
end
|
data/lib/yard/logging.rb
CHANGED
@@ -1,24 +1,50 @@
|
|
1
1
|
require 'logger'
|
2
|
+
require 'thread'
|
2
3
|
|
3
4
|
module YARD
|
4
5
|
# Handles console logging for info, warnings and errors.
|
5
6
|
# Uses the stdlib Logger class in Ruby for all the backend logic.
|
6
7
|
class Logger < ::Logger
|
7
|
-
|
8
|
+
# The list of characters displayed beside the progress bar to indicate
|
9
|
+
# "movement".
|
10
|
+
# @since 0.8.2
|
11
|
+
PROGRESS_INDICATORS = ["\u230C", "\u230D", "\u230E", "\u230F"]
|
12
|
+
|
13
|
+
# @return [IO] the IO object being logged to
|
14
|
+
# @since 0.8.2
|
15
|
+
attr_accessor :io
|
16
|
+
|
17
|
+
# @return [Boolean] whether backtraces should be shown (by default
|
18
|
+
# this is on).
|
8
19
|
def show_backtraces; @show_backtraces || level == DEBUG end
|
20
|
+
attr_writer :show_backtraces
|
21
|
+
|
22
|
+
# @return [Boolean] whether progress indicators should be shown when
|
23
|
+
# logging CLIs (by default this is off).
|
24
|
+
def show_progress
|
25
|
+
return false if RUBY18 # threading is too ineffective for progress support
|
26
|
+
return false unless io.tty? # no TTY support on IO
|
27
|
+
return false if level > WARN # no progress in verbose/debug modes
|
28
|
+
@show_progress
|
29
|
+
end
|
30
|
+
attr_writer :show_progress
|
9
31
|
|
10
32
|
# The logger instance
|
11
33
|
# @return [Logger] the logger instance
|
12
|
-
def self.instance(pipe =
|
34
|
+
def self.instance(pipe = STDOUT)
|
13
35
|
@logger ||= new(pipe)
|
14
36
|
end
|
15
37
|
|
16
38
|
# Creates a new logger
|
17
|
-
def initialize(*args)
|
18
|
-
super
|
39
|
+
def initialize(pipe, *args)
|
40
|
+
super(pipe, *args)
|
41
|
+
self.io = pipe
|
19
42
|
self.show_backtraces = true
|
43
|
+
self.show_progress = false
|
20
44
|
self.level = WARN
|
21
45
|
self.formatter = method(:format_log)
|
46
|
+
@progress_indicator = 0
|
47
|
+
@mutex = Mutex.new
|
22
48
|
end
|
23
49
|
|
24
50
|
# Changes the debug level to DEBUG if $DEBUG is set
|
@@ -28,15 +54,80 @@ module YARD
|
|
28
54
|
super
|
29
55
|
end
|
30
56
|
|
57
|
+
# Captures the duration of a block of code for benchmark analysis. Also
|
58
|
+
# calls {#progress} on the message to display it to the user.
|
59
|
+
#
|
60
|
+
# @todo Implement capture storage for reporting of benchmarks
|
61
|
+
# @param [String] msg the message to display
|
62
|
+
# @param [Symbol, nil] nontty_log the level to log as if the output
|
63
|
+
# stream is not a TTY. Use +nil+ for no alternate logging.
|
64
|
+
# @yield a block of arbitrary code to benchmark
|
65
|
+
# @return [void]
|
66
|
+
def capture(msg, nontty_log = :debug, &block)
|
67
|
+
progress(msg, nontty_log)
|
68
|
+
yield
|
69
|
+
ensure
|
70
|
+
clear_progress
|
71
|
+
end
|
72
|
+
|
73
|
+
# Displays a progress indicator for a given message. This progress report
|
74
|
+
# is only displayed on TTY displays, otherwise the message is passed to
|
75
|
+
# the +nontty_log+ level.
|
76
|
+
#
|
77
|
+
# @param [String] msg the message to log
|
78
|
+
# @param [Symbol, nil] nontty_log the level to log as if the output
|
79
|
+
# stream is not a TTY. Use +nil+ for no alternate logging.
|
80
|
+
# @return [void]
|
81
|
+
# @since 0.8.2
|
82
|
+
def progress(msg, nontty_log = :debug)
|
83
|
+
send(nontty_log, msg) if nontty_log
|
84
|
+
return unless show_progress
|
85
|
+
icon = ""
|
86
|
+
if defined?(::Encoding)
|
87
|
+
icon = PROGRESS_INDICATORS[@progress_indicator] + " "
|
88
|
+
end
|
89
|
+
self << "\e[2K\e[?25l\e[1m#{icon}#{msg}\e[0m\r"
|
90
|
+
@mutex.synchronize do
|
91
|
+
@progress_msg = msg
|
92
|
+
@progress_indicator += 1
|
93
|
+
@progress_indicator %= PROGRESS_INDICATORS.size
|
94
|
+
end
|
95
|
+
Thread.new do
|
96
|
+
sleep(0.05)
|
97
|
+
@mutex.synchronize do
|
98
|
+
progress(msg + ".", nil) if @progress_msg == msg
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Clears the progress indicator in the TTY display.
|
104
|
+
# @return [void]
|
105
|
+
# @since 0.8.2
|
106
|
+
def clear_progress
|
107
|
+
return unless show_progress
|
108
|
+
self << "\e[?25h\e[2K"
|
109
|
+
@progress_msg = nil
|
110
|
+
end
|
111
|
+
|
112
|
+
# Displays an unformatted line to the logger output stream. Similar to
|
113
|
+
# the +#<<+ method, but adds a newline.
|
114
|
+
# @param [String] msg the message to display
|
115
|
+
# @return [void]
|
116
|
+
# @since 0.8.2
|
117
|
+
def puts(msg)
|
118
|
+
self << "#{msg}\n"
|
119
|
+
end
|
120
|
+
|
31
121
|
# Prints the backtrace +exc+ to the logger as error data.
|
32
122
|
#
|
33
123
|
# @param [Array<String>] exc the backtrace list
|
124
|
+
# @param [Symbol] level_meth the level to log backtrace at
|
34
125
|
# @return [void]
|
35
|
-
def backtrace(exc)
|
126
|
+
def backtrace(exc, level_meth = :error)
|
36
127
|
return unless show_backtraces
|
37
|
-
|
38
|
-
|
39
|
-
exc.backtrace[0..5].map {|x| "\n\t#{x}" }.join + "\n"
|
128
|
+
send(level_meth, "#{exc.class.class_name}: #{exc.message}")
|
129
|
+
send(level_meth, "Stack trace:" +
|
130
|
+
exc.backtrace[0..5].map {|x| "\n\t#{x}" }.join + "\n")
|
40
131
|
end
|
41
132
|
|
42
133
|
# Warns that the Ruby environment does not support continuations. Applies
|