todonotes 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/todonotes_how_to.rb +32 -12
- data/examples/todonotes_prim.rb +14 -5
- data/examples/todonotes_prim2.rb +16 -5
- data/lib/todonotes.rb +42 -153
- data/lib/todonotes/kernel.rb +40 -0
- data/lib/todonotes/log4r.rb +24 -0
- data/lib/todonotes/todo.rb +58 -0
- data/lib/todonotes/todonotes.rb +97 -0
- data/{readme.rd → readme.rdoc} +23 -16
- data/unittest/unittest_todonotes.rb +80 -29
- metadata +51 -61
@@ -1,38 +1,58 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
Examples of the different syntax version of the fixme/and todo-command.
|
3
|
+
=end
|
1
4
|
$:.unshift('../lib')
|
2
5
|
require 'todonotes'
|
3
6
|
|
7
|
+
#a ToDo with default text 'ToDo' and without temporary result
|
4
8
|
to do
|
5
|
-
"
|
9
|
+
"my temporary result"
|
6
10
|
end
|
7
11
|
|
8
|
-
|
12
|
+
#a ToDo without temporary result
|
13
|
+
todo "my description of the missing code"
|
9
14
|
|
10
|
-
|
15
|
+
#a ToDo without description, but a temporary result
|
16
|
+
todo { "my temporary result" }
|
11
17
|
|
12
|
-
|
18
|
+
#a ToDo with description and temporary result
|
19
|
+
todo ('my description of the missing code' ) { "my temporary result" }
|
13
20
|
|
21
|
+
|
22
|
+
#a ToDo without description, but a temporary result
|
14
23
|
todo do
|
15
|
-
"
|
24
|
+
"my temporary result"
|
16
25
|
end
|
17
26
|
|
27
|
+
#a ToDo with description and temporary result
|
18
28
|
todo 'Text' do
|
19
|
-
"
|
29
|
+
"my temporary result"
|
20
30
|
end
|
21
31
|
|
22
32
|
####################
|
23
|
-
2.times { fixme "mein Text" }
|
24
33
|
|
25
|
-
|
34
|
+
#a FixMe without description, but a temporary result
|
35
|
+
fixme { "my temporary result" }
|
26
36
|
|
27
|
-
|
37
|
+
#a FixMe with description and temporary result
|
38
|
+
fixme ('my description if the wrong code' ) { "my temporary result" }
|
28
39
|
|
40
|
+
#a FixMe without description, but a temporary result
|
29
41
|
fixme do
|
30
|
-
"
|
42
|
+
"my temporary result"
|
31
43
|
end
|
32
44
|
|
33
|
-
|
34
|
-
|
45
|
+
#a FixMe with description and temporary result
|
46
|
+
fixme 'my description if the wrong code' do
|
47
|
+
"my temporary result"
|
35
48
|
end
|
49
|
+
####################
|
50
|
+
#a Fixme is called twice
|
51
|
+
2.times { fixme "my description of the missing code" }
|
52
|
+
#a ToDo is called three times
|
53
|
+
3.times { todo "my description of the missing code" }
|
54
|
+
|
36
55
|
####################
|
37
56
|
|
57
|
+
#Get an overview of all ToDos and FixMes
|
38
58
|
Todonotes.print_stats
|
data/examples/todonotes_prim.rb
CHANGED
@@ -1,13 +1,22 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
=Example of usage fixme/todo
|
3
|
+
Write a script to count all prime between 1 to 10.
|
4
|
+
|
5
|
+
For each number, write a message like
|
6
|
+
x is [a|no] prime number
|
7
|
+
|
8
|
+
Until you know, how to determine, if a number is a prime,
|
9
|
+
you can take the temporary algorithm: each odd number is a prime.
|
10
|
+
=end
|
1
11
|
$:.unshift('../lib')
|
2
12
|
require 'todonotes'
|
3
13
|
|
4
14
|
#
|
5
|
-
#
|
6
|
-
Todonotes.
|
7
|
-
Todonotes.instance.logger.level = Log4r::INFO #report all calls of fixme/todo
|
15
|
+
Todonotes.logger.level = Log4r::WARN #only first time of callinf a fixme/todo
|
16
|
+
#~ Todonotes.logger.level = Log4r::INFO #report all calls of fixme/todo
|
8
17
|
|
9
18
|
primecount = 0
|
10
|
-
|
19
|
+
10.times do|i|
|
11
20
|
if fixme "Calculate if prime" do
|
12
21
|
i.odd? #tempory: odd = prim
|
13
22
|
end
|
@@ -21,5 +30,5 @@ end
|
|
21
30
|
todo "Return total number of primes"
|
22
31
|
|
23
32
|
#Details
|
24
|
-
Todonotes.print_stats()
|
33
|
+
puts Todonotes.print_stats()
|
25
34
|
|
data/examples/todonotes_prim2.rb
CHANGED
@@ -1,12 +1,23 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
=Example of usage fixme/todo
|
3
|
+
Write a script to count all prime between 1 to 10.
|
4
|
+
|
5
|
+
For each number, write a message like
|
6
|
+
x is [a|no] prime number
|
7
|
+
|
8
|
+
Until you know, how to determine, if a number is a prime,
|
9
|
+
you can take the temporary algorithm: each odd number is a prime.
|
10
|
+
=end
|
1
11
|
$:.unshift('../lib')
|
2
12
|
require 'todonotes'
|
3
13
|
|
4
14
|
#
|
5
|
-
#
|
6
|
-
Todonotes.
|
7
|
-
Todonotes.instance.logger.level = Log4r::INFO #report all calls of fixme/todo
|
15
|
+
Todonotes.logger.level = Log4r::WARN #only first time of callinf a fixme/todo
|
16
|
+
Todonotes.logger.level = Log4r::INFO #report all calls of fixme/todo
|
8
17
|
|
9
18
|
class Fixnum
|
19
|
+
#Decide if Fixnum is a prime.
|
20
|
+
#This method is only a temporarysolution.
|
10
21
|
def prime?
|
11
22
|
fixme "Calculate if prime" do
|
12
23
|
self.odd? #tempory: odd = prim
|
@@ -15,7 +26,7 @@ class Fixnum
|
|
15
26
|
end
|
16
27
|
|
17
28
|
primecount = 0
|
18
|
-
|
29
|
+
10.times do|i|
|
19
30
|
if i.prime?
|
20
31
|
primecount += 1
|
21
32
|
puts "#{i} is a prime number"
|
@@ -27,6 +38,6 @@ end
|
|
27
38
|
todo "Return total number of primes"
|
28
39
|
|
29
40
|
#Details
|
30
|
-
Todonotes.print_stats()
|
41
|
+
puts Todonotes.print_stats()
|
31
42
|
|
32
43
|
|
data/lib/todonotes.rb
CHANGED
@@ -26,186 +26,75 @@ Gem based on a proposal in http://forum.ruby-portal.de/viewtopic.php?f=11&t=1195
|
|
26
26
|
require 'singleton'
|
27
27
|
require 'log4r'
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
=begin rdoc
|
34
|
-
If event is an Array, the output is adapted.
|
35
|
-
|
36
|
-
This outputter is only for internal use via Todonotes.
|
37
|
-
=end
|
38
|
-
def format(event)
|
39
|
-
#@@basicformat "%*s %s"
|
40
|
-
#~ buff = sprintf("%-*s %-5s", Log4r::MaxLevelLength, Log4r::LNAMES[event.level],
|
41
|
-
#~ event.data.is_a?(Array) ? event.data.first : event.name)
|
42
|
-
buff = "%-5s" % (event.data.is_a?(Array) ? event.data.first : event.name)
|
43
|
-
#~ buff += (event.tracer.nil? ? "" : "(#{event.tracer[2]})") + ": "
|
44
|
-
buff << ": "
|
45
|
-
buff << format_object(event.data.is_a?(Array) ? event.data.last : event.data)
|
46
|
-
buff << (event.tracer.nil? ? "" : " (#{event.tracer.join('/')})")
|
47
|
-
buff << "\n"
|
48
|
-
buff
|
49
|
-
end
|
50
|
-
end
|
29
|
+
require_relative 'todonotes/todonotes'
|
30
|
+
require_relative 'todonotes/todo'
|
31
|
+
require_relative 'todonotes/log4r'
|
32
|
+
require_relative 'todonotes/kernel'
|
51
33
|
|
52
34
|
=begin rdoc
|
53
|
-
|
35
|
+
Module Todonotes.
|
54
36
|
|
55
|
-
|
56
|
-
*
|
57
|
-
*
|
58
|
-
* FiXme#codeline get Hash with counter per ToDo-locations.
|
59
|
-
* FiXme#overview get overview text with ToDo-locations.
|
37
|
+
Encapsuate:
|
38
|
+
* Todonotes::Todonotes (Singleton)
|
39
|
+
* Todonotes::FixmeFormatter
|
60
40
|
=end
|
61
|
-
|
62
|
-
VERSION = '0.1.
|
63
|
-
|
41
|
+
module Todonotes
|
42
|
+
VERSION = '0.1.1'
|
43
|
+
#'singleton'-instance of Todonotes
|
44
|
+
TODONOTES = Todonotes.new()
|
64
45
|
=begin rdoc
|
65
|
-
Define
|
66
|
-
=end
|
67
|
-
def initialize()
|
68
|
-
# @codeline is a Hash with Filename and codeline (key). Value is the number of calls.
|
69
|
-
@codeline = Hash.new(0)
|
70
|
-
@logger = Log4r::Logger.new('ToDo')
|
71
|
-
@logger.outputters = Log4r::StdoutOutputter.new('ToDo',
|
72
|
-
:level => Log4r::ALL,
|
73
|
-
:formatter => Log4r::FixmeFormatter
|
74
|
-
)
|
75
|
-
#~ @logger.trace = true
|
76
|
-
end
|
77
|
-
#Get logger to define alternative outputters...
|
78
|
-
attr_reader :logger
|
79
|
-
=begin rdoc
|
80
|
-
Write the todo's in a logging file.
|
81
|
-
|
82
|
-
Default filename is $0.todo
|
46
|
+
Define module-methods
|
83
47
|
=end
|
84
|
-
|
85
|
-
@logger.add( Log4r::FileOutputter.new('ToDo',
|
86
|
-
:filename => filename,
|
87
|
-
:level => level,
|
88
|
-
:formatter => Log4r::FixmeFormatter
|
89
|
-
))
|
48
|
+
class << self
|
90
49
|
|
91
|
-
end
|
92
|
-
#Direct access to the codeline list. See also #todo_overview
|
93
|
-
attr_reader :codeline
|
94
50
|
=begin rdoc
|
95
|
-
|
96
|
-
|
97
|
-
The comment is logged,
|
98
|
-
the block is evaluated to get a temporary result.
|
51
|
+
See Todonotes::Todonotes#overview
|
99
52
|
=end
|
100
|
-
|
101
|
-
|
102
|
-
key = caller[1].split(':in').first
|
103
|
-
if block_given?
|
104
|
-
res = yield self
|
105
|
-
res
|
53
|
+
def print_stats( with_type = false )
|
54
|
+
TODONOTES.overview( with_type )
|
106
55
|
end
|
107
|
-
log_todo(key, type, comment, res)
|
108
|
-
#~ @logger.debug("Return #{res.inspect} instead") if @logger.debug?
|
109
|
-
res
|
110
|
-
end
|
111
56
|
=begin rdoc
|
112
|
-
|
113
|
-
|
114
|
-
The first occurence is reported as a warning,
|
115
|
-
next occurences are informations.
|
57
|
+
See Todonotes::Todonotes#overview
|
116
58
|
=end
|
117
|
-
|
118
|
-
|
119
|
-
@codeline[key] += 1
|
120
|
-
if @codeline[key] == 1 #First occurence?
|
121
|
-
@logger.warn([type, "#{key} #{text} (temporary: #{res.inspect})"])
|
122
|
-
else #Erste auftauchen
|
123
|
-
@logger.info([type, "#{key}(#{@codeline[key]}) #{text} (temporary: #{res.inspect})"])
|
59
|
+
def overview(*settings )
|
60
|
+
TODONOTES.overview( *settings )
|
124
61
|
end
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
62
|
=begin rdoc
|
129
|
-
|
130
|
-
puts Todonotes.instance.todo_overview()
|
131
|
-
Used from Todonotes.print_stats
|
132
|
-
|
133
|
-
Example:
|
134
|
-
List of ToDos/FixMes:
|
135
|
-
fixme.rb:195: 1 call
|
136
|
-
fixme.rb:198: 2 calls
|
137
|
-
fixme.rb:199: 1 call
|
138
|
-
fixme.rb:200: 1 call
|
63
|
+
See Todonotes::Todonotes#codelines
|
139
64
|
=end
|
140
|
-
|
141
|
-
|
142
|
-
txt << "List of ToDos/FixMes:"
|
143
|
-
@codeline.each do |key, messages|
|
144
|
-
txt << "%s: %4i call%s" % [ key, messages, messages > 1 ? 's': '' ]
|
65
|
+
def codelines()
|
66
|
+
TODONOTES.codelines()
|
145
67
|
end
|
146
|
-
txt.join("\n")
|
147
|
-
end
|
148
|
-
|
149
|
-
=begin rdoc
|
150
|
-
Class methods
|
151
|
-
=end
|
152
|
-
class << self
|
153
68
|
=begin rdoc
|
154
|
-
See Todonotes#
|
69
|
+
See Todonotes::Todonotes#logger
|
155
70
|
=end
|
156
|
-
def
|
157
|
-
|
71
|
+
def logger()
|
72
|
+
TODONOTES.logger()
|
158
73
|
end
|
159
|
-
end #<< self
|
160
|
-
end
|
161
|
-
|
162
|
-
=begin rdoc
|
163
|
-
Define todo-commands to global usage.
|
164
|
-
=end
|
165
|
-
module Kernel
|
166
74
|
=begin rdoc
|
167
|
-
|
168
|
-
todo "my todo-message""
|
169
|
-
|
170
|
-
Usage 2 (only temporary result):
|
171
|
-
todo { "temporary result" }
|
172
|
-
todo do
|
173
|
-
"temporary result"
|
174
|
-
end
|
175
|
-
|
176
|
-
Usage 3(message and temporary result):
|
177
|
-
todo ('message') { "temporary result" }
|
178
|
-
todo ('message') do
|
179
|
-
"temporary result"
|
180
|
-
end
|
181
|
-
|
75
|
+
See Todonotes::Todonotes#log2file
|
182
76
|
=end
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
to do
|
189
|
-
:result
|
190
|
-
end
|
191
|
-
=end
|
192
|
-
alias :to :todo
|
193
|
-
=begin rdoc
|
194
|
-
Add a fixme-command.
|
77
|
+
def log2file(filename = File.basename($0) + '.todo', level = Log4r::ALL)
|
78
|
+
TODONOTES.log2file(filename, level)
|
79
|
+
end
|
80
|
+
end #Todonotes-module mthods
|
81
|
+
end #module Todonotes
|
195
82
|
|
196
|
-
Can be used to mark available code.
|
197
|
-
=end
|
198
|
-
def fixme( comment = 'FixMe', &block)
|
199
|
-
Todonotes.instance.todo(comment, :FixMe, &block)
|
200
|
-
end
|
201
|
-
end
|
202
83
|
|
84
|
+
#Some testcode as "quick test"
|
203
85
|
if $0 == __FILE__
|
86
|
+
|
204
87
|
todo( 'a' ){
|
205
88
|
"result"
|
206
89
|
}
|
207
90
|
2.times{todo { "result" }}
|
208
91
|
fixme { "result" }
|
209
92
|
to('a')
|
210
|
-
Todonotes.print_stats( )
|
211
|
-
|
93
|
+
#~ Todonotes.print_stats( )
|
94
|
+
#~ puts Todonotes.overview( )
|
95
|
+
#~ puts Todonotes.overview( :with_type )
|
96
|
+
#~ puts Todonotes.overview( :with_type, :with_shortdescription )
|
97
|
+
puts Todonotes.overview( :with_type, :with_shortdescription, :with_result )
|
98
|
+
|
99
|
+
puts Todonotes.codelines( )
|
100
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
Define todo- and fixme commands to global usage.
|
3
|
+
=end
|
4
|
+
module Kernel
|
5
|
+
=begin rdoc
|
6
|
+
Usage 1 (only message):
|
7
|
+
todo "my todo-message""
|
8
|
+
|
9
|
+
Usage 2 (only temporary result):
|
10
|
+
todo { "temporary result" }
|
11
|
+
todo do
|
12
|
+
"temporary result"
|
13
|
+
end
|
14
|
+
|
15
|
+
Usage 3(message and temporary result):
|
16
|
+
todo ('message') { "temporary result" }
|
17
|
+
todo ('message') do
|
18
|
+
"temporary result"
|
19
|
+
end
|
20
|
+
|
21
|
+
=end
|
22
|
+
def todo( comment = 'ToDo', &block)
|
23
|
+
Todonotes::TODONOTES.todo(comment, &block)
|
24
|
+
end
|
25
|
+
=begin rdoc
|
26
|
+
Usage:
|
27
|
+
to do
|
28
|
+
:result
|
29
|
+
end
|
30
|
+
=end
|
31
|
+
alias :to :todo
|
32
|
+
=begin rdoc
|
33
|
+
Add a fixme-command.
|
34
|
+
|
35
|
+
Can be used to mark available code.
|
36
|
+
=end
|
37
|
+
def fixme( comment = 'FixMe', &block)
|
38
|
+
Todonotes::TODONOTES.todo(comment, :FixMe, &block)
|
39
|
+
end
|
40
|
+
end #module Kernel
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Todonotes
|
2
|
+
=begin rdoc
|
3
|
+
Define a formatter.
|
4
|
+
=end
|
5
|
+
class FixmeFormatter < Log4r::BasicFormatter
|
6
|
+
=begin rdoc
|
7
|
+
If event is an Array, the output is adapted.
|
8
|
+
|
9
|
+
This outputter is only for internal use via Todonotes.
|
10
|
+
=end
|
11
|
+
def format(event)
|
12
|
+
#@@basicformat "%*s %s"
|
13
|
+
#~ buff = sprintf("%-*s %-5s", Log4r::MaxLevelLength, Log4r::LNAMES[event.level],
|
14
|
+
#~ event.data.is_a?(Array) ? event.data.first : event.name)
|
15
|
+
buff = "%-5s" % (event.data.is_a?(Array) ? event.data.first : event.name)
|
16
|
+
#~ buff += (event.tracer.nil? ? "" : "(#{event.tracer[2]})") + ": "
|
17
|
+
buff << ": "
|
18
|
+
buff << format_object(event.data.is_a?(Array) ? event.data.last : event.data)
|
19
|
+
buff << (event.tracer.nil? ? "" : " (#{event.tracer.join('/')})")
|
20
|
+
buff << "\n"
|
21
|
+
buff
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end #module Todonotes
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Todonotes
|
2
|
+
=begin rdoc
|
3
|
+
Report the ToDo/FixMe and count occurence.
|
4
|
+
|
5
|
+
The first occurence is reported as a warning,
|
6
|
+
next occurences are informations.
|
7
|
+
=end
|
8
|
+
class Todo
|
9
|
+
=begin rdoc
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
=end
|
14
|
+
def initialize(codeline, type, comment, logger, &block)
|
15
|
+
@logger = logger
|
16
|
+
@count = 1
|
17
|
+
@codeline = codeline
|
18
|
+
@type = type
|
19
|
+
@shortdescription = comment
|
20
|
+
#Build result
|
21
|
+
@result = yield if block_given?
|
22
|
+
|
23
|
+
@logger.warn([@type, "#{@codeline} #{@shortdescription} (temporary: #{@result.inspect})"])
|
24
|
+
|
25
|
+
end
|
26
|
+
#Temporary result of the Todo. This result should become a 'real' value
|
27
|
+
attr_reader :result
|
28
|
+
attr_reader :short_description
|
29
|
+
attr_reader :count
|
30
|
+
=begin rdoc
|
31
|
+
Todo/Fixme is called again
|
32
|
+
=end
|
33
|
+
def call()
|
34
|
+
@logger.info([@type, "#{@codeline}(#{@count}) #{@shortdescription} (temporary: #{@result.inspect})"])
|
35
|
+
@count += 1
|
36
|
+
end
|
37
|
+
=begin rdoc
|
38
|
+
=end
|
39
|
+
def to_s()
|
40
|
+
"#{@type}: #{@codeline}"
|
41
|
+
end
|
42
|
+
=begin rdoc
|
43
|
+
Return a single line with status of the todo.
|
44
|
+
|
45
|
+
Depending on with_type you get also the type (ToDo/FixMe)
|
46
|
+
=end
|
47
|
+
def infoline(settings)
|
48
|
+
res = @codeline.dup
|
49
|
+
res << " (%-5s)" % @type if settings.include?(:with_type)
|
50
|
+
res << ": %4i call%s" % [
|
51
|
+
@count, @count > 1 ? 's': ''
|
52
|
+
]
|
53
|
+
res << " (%s)" % @shortdescription if settings.include?(:with_shortdescription)
|
54
|
+
res << " = '#{@result.inspect}'" if settings.include?(:with_result)
|
55
|
+
res
|
56
|
+
end #info
|
57
|
+
end #class Codeline
|
58
|
+
end #module Todonotes
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Todonotes
|
2
|
+
=begin rdoc
|
3
|
+
Collection of todos and fixmes.
|
4
|
+
|
5
|
+
The module Todonotes defines a 'singleton'-like
|
6
|
+
Todonotes::TODONOTES to collect all todo/fixme from Kernel.
|
7
|
+
|
8
|
+
You can set settings with
|
9
|
+
* Todonotes::Todonotes#log2file Define log file
|
10
|
+
* Todonotes::Todonotes#logger adapt level, outputter ...
|
11
|
+
* Todonotes::Todonotes#codelines get Hash with counter per ToDo-locations.
|
12
|
+
* Todonotes::Todonotes#overview get overview text with ToDo-locations.
|
13
|
+
=end
|
14
|
+
class Todonotes
|
15
|
+
|
16
|
+
=begin rdoc
|
17
|
+
Define the singleton-instance.
|
18
|
+
=end
|
19
|
+
def initialize()
|
20
|
+
@codelines = Hash.new()
|
21
|
+
|
22
|
+
@logger = Log4r::Logger.new('ToDo')
|
23
|
+
@logger.outputters = Log4r::StdoutOutputter.new('ToDo',
|
24
|
+
:level => Log4r::ALL,
|
25
|
+
:formatter => FixmeFormatter
|
26
|
+
)
|
27
|
+
#~ @logger.trace = true
|
28
|
+
end
|
29
|
+
#Get logger to define alternative outputters...
|
30
|
+
attr_reader :logger
|
31
|
+
=begin rdoc
|
32
|
+
Write the todo's in a logging file.
|
33
|
+
|
34
|
+
Default filename is $0.todo
|
35
|
+
=end
|
36
|
+
def log2file(filename = File.basename($0) + '.todo', level = Log4r::ALL)
|
37
|
+
@logger.add( Log4r::FileOutputter.new('ToDo',
|
38
|
+
:filename => filename,
|
39
|
+
:level => level,
|
40
|
+
:formatter => FixmeFormatter
|
41
|
+
))
|
42
|
+
|
43
|
+
end
|
44
|
+
#Direct access to the codelines list. See also #overview
|
45
|
+
#Accessible via Todonotes::Todonotes.instance.codelines()
|
46
|
+
attr_reader :codelines
|
47
|
+
=begin rdoc
|
48
|
+
Report a FixMe or a ToDo.
|
49
|
+
Create a Todonotes::Todo
|
50
|
+
|
51
|
+
The block is evaluated to get a temporary result.
|
52
|
+
=end
|
53
|
+
def todo( comment, type = :ToDo, &block)
|
54
|
+
codeline = caller[1].split(':in').first
|
55
|
+
codelinekey = "#{codeline} (#{type})"
|
56
|
+
|
57
|
+
if @codelines[codelinekey] #2nd or more calls
|
58
|
+
@codelines[codelinekey].call
|
59
|
+
else #First occurence?
|
60
|
+
@codelines[codelinekey] = Todo.new(codeline, type, comment, @logger, &block)
|
61
|
+
end
|
62
|
+
@codelines[codelinekey].result
|
63
|
+
end #todo
|
64
|
+
|
65
|
+
=begin rdoc
|
66
|
+
Return a text to be printed
|
67
|
+
puts Todonotes.overview()
|
68
|
+
Used from Todonotes.print_stats
|
69
|
+
|
70
|
+
Example:
|
71
|
+
List of ToDos/FixMes:
|
72
|
+
todonotes.rb:230: 1 call
|
73
|
+
todonotes.rb:233: 2 calls
|
74
|
+
todonotes.rb:234: 1 call
|
75
|
+
todonotes.rb:235: 1 call
|
76
|
+
|
77
|
+
You may extend the output by parameters:
|
78
|
+
* :with_type
|
79
|
+
* :with_shortdescription
|
80
|
+
* :with_result
|
81
|
+
|
82
|
+
Example :with_type:
|
83
|
+
todonotes.rb:230 (ToDo): 1 call
|
84
|
+
todonotes.rb:233 (ToDo): 2 calls
|
85
|
+
todonotes.rb:234 (FixMe): 1 call
|
86
|
+
todonotes.rb:235 (ToDo): 1 call
|
87
|
+
=end
|
88
|
+
def overview( *settings )
|
89
|
+
txt = []
|
90
|
+
txt << "List of ToDos/FixMes:"
|
91
|
+
@codelines.each do |key, todo|
|
92
|
+
txt << todo.infoline(settings)
|
93
|
+
end
|
94
|
+
txt.join("\n")
|
95
|
+
end
|
96
|
+
end #class Todonotes
|
97
|
+
end #module Todonotes
|
data/{readme.rd → readme.rdoc}
RENAMED
@@ -1,10 +1,12 @@
|
|
1
|
-
=
|
2
|
-
Define todo- and fixme-command.
|
1
|
+
=todonotes
|
2
|
+
Define todo- and fixme-command to mark open topics during software development.
|
3
3
|
|
4
4
|
==Usage:
|
5
|
-
Add
|
5
|
+
Add _todo_ and _fixme_ to your code and get track of your todos during
|
6
6
|
runtime of your code.
|
7
7
|
|
8
|
+
Productive programms should not use this gem.
|
9
|
+
|
8
10
|
When you pass a todo/fixme during execution, you get a logging information.
|
9
11
|
|
10
12
|
todo ('message' ) { "temporary result" }
|
@@ -12,13 +14,13 @@ When you pass a todo/fixme during execution, you get a logging information.
|
|
12
14
|
|
13
15
|
todo and fixme have the same syntax, the sematic meaning is:
|
14
16
|
* ToDo: Mark missing code.
|
15
|
-
*
|
17
|
+
* FixMe: Mark code to repair.
|
16
18
|
|
17
19
|
Disadvantage:
|
18
|
-
* Does not replace a good IDE.
|
19
|
-
|
20
|
+
* Does not replace a good IDE to find the ToDo/Fixmes.
|
21
|
+
|
20
22
|
|
21
|
-
Gem based on a proposal in http://forum.ruby-portal.de/viewtopic.php?f=11&t=11957
|
23
|
+
This Gem is based on a proposal in http://forum.ruby-portal.de/viewtopic.php?f=11&t=11957
|
22
24
|
|
23
25
|
=Example
|
24
26
|
|
@@ -31,7 +33,7 @@ So you can start your program:
|
|
31
33
|
|
32
34
|
primecount = 0
|
33
35
|
for i in 1..10
|
34
|
-
if fixme "Calculate if prime,
|
36
|
+
if fixme "Calculate if prime, temporary: true for odd numbers" do
|
35
37
|
i.odd? #tempory: odd = prim
|
36
38
|
end
|
37
39
|
primecount += 1
|
@@ -67,11 +69,11 @@ Or
|
|
67
69
|
|
68
70
|
Now you get a output like this:
|
69
71
|
|
70
|
-
|
72
|
+
FixMe: todonotes_prim2.rb:12 Calculate if prime misssing (temporary: true)
|
71
73
|
1 is a prime number
|
72
|
-
|
74
|
+
FixMe: todonotes_prim2.rb:12(2) Calculate if prime misssing (temporary: false)
|
73
75
|
2 is no prime number
|
74
|
-
|
76
|
+
FixMe: todonotes_prim2.rb:12(3) Calculate if prime misssing (temporary: true)
|
75
77
|
...
|
76
78
|
ToDo : todonotes_prim2.rb:27 Return total number of primes (temporary: nil)
|
77
79
|
|
@@ -85,25 +87,30 @@ You are informed about source code file and line number. In braces you get the n
|
|
85
87
|
The todo/fixme command evaluates the optional block.
|
86
88
|
The result is returned as a temporary result (in this example: odd numbers are primes.).
|
87
89
|
|
90
|
+
|
91
|
+
Please refer the examples folder for more details.
|
92
|
+
|
88
93
|
==Logging
|
89
94
|
|
90
|
-
The Fixme and ToDo are reported via a logger.
|
95
|
+
The Fixme's and ToDo's are reported via a logger (log4r).
|
96
|
+
|
91
97
|
The first call of a fixme/todo is a warning, the next call is an information.
|
98
|
+
With this logic you can decide, if you want to see each call or only the first call.
|
92
99
|
|
93
100
|
|
94
101
|
You may change the level with:
|
95
|
-
Todonotes.
|
96
|
-
Todonotes.
|
102
|
+
Todonotes.logger.level = Log4r::WARN #only first time of a call of a fixme/todo
|
103
|
+
Todonotes.logger.level = Log4r::INFO #report all calls of fixme/todo
|
97
104
|
|
98
105
|
You can log the fixme/todos to a file:
|
99
|
-
Todonotes.
|
106
|
+
Todonotes.log2file()
|
100
107
|
|
101
108
|
==Get Overview
|
102
109
|
You may print an overview on all fixme/todos:
|
103
110
|
Todonotes.print_stats()
|
104
111
|
|
105
112
|
Example:
|
106
|
-
List of ToDos/
|
113
|
+
List of ToDos/Fixmes:
|
107
114
|
todonotes_prim.rb:11: 10 calls
|
108
115
|
todonotes_prim.rb:21: 1 call
|
109
116
|
|
@@ -26,10 +26,10 @@ Clear message array and return messages
|
|
26
26
|
end
|
27
27
|
end #ArrayOutputter
|
28
28
|
|
29
|
-
#~ Todonotes.
|
30
|
-
Todonotes.
|
31
|
-
Todonotes.
|
32
|
-
$testlog.formatter =
|
29
|
+
#~ Todonotes::TODONOTES.logger.level = Log4r::OFF #No logging
|
30
|
+
Todonotes::TODONOTES.logger.outputters.first.level = Log4r::OFF
|
31
|
+
Todonotes::TODONOTES.logger.outputters << $testlog = ArrayOutputter.new('testlog')
|
32
|
+
$testlog.formatter = Todonotes::FixmeFormatter.new
|
33
33
|
|
34
34
|
class Test_syntax < Test::Unit::TestCase
|
35
35
|
def test_todo()
|
@@ -113,35 +113,87 @@ class Test_value_and_log < Test::Unit::TestCase
|
|
113
113
|
end
|
114
114
|
|
115
115
|
class Test_overview < Test::Unit::TestCase
|
116
|
+
def setup()
|
117
|
+
Todonotes::TODONOTES.codelines.clear
|
118
|
+
end
|
116
119
|
def test_overview()
|
117
|
-
Todonotes.instance.codeline.clear
|
118
|
-
|
119
120
|
#check empty fixme/todo
|
120
121
|
text = "List of ToDos/FixMes:"
|
121
|
-
codeline =
|
122
|
-
assert_equal(text, Todonotes.
|
123
|
-
assert_equal(codeline, Todonotes.
|
124
|
-
|
122
|
+
codeline = []
|
123
|
+
assert_equal(text, Todonotes::TODONOTES.overview())
|
124
|
+
assert_equal(codeline, Todonotes::TODONOTES.codelines.keys)
|
125
|
+
#Check class methods
|
126
|
+
assert_equal(Todonotes.overview(), Todonotes::TODONOTES.overview())
|
127
|
+
assert_equal(Todonotes.codelines, Todonotes::TODONOTES.codelines)
|
128
|
+
|
125
129
|
line = __LINE__; fixme('a')
|
126
130
|
text << "\n#{__FILE__}:#{line}: 1 call"
|
127
|
-
codeline
|
128
|
-
assert_equal(text, Todonotes.
|
129
|
-
assert_equal(codeline, Todonotes.
|
131
|
+
codeline << "#{__FILE__}:#{line} (FixMe)"
|
132
|
+
assert_equal(text, Todonotes::TODONOTES.overview())
|
133
|
+
assert_equal(codeline, Todonotes::TODONOTES.codelines.keys)
|
134
|
+
#Check class methods
|
135
|
+
assert_equal(Todonotes.overview(), Todonotes::TODONOTES.overview())
|
136
|
+
assert_equal(Todonotes.codelines, Todonotes::TODONOTES.codelines)
|
130
137
|
|
131
138
|
#Add 2nd todo
|
132
139
|
line = __LINE__; fixme('b')
|
133
140
|
text << "\n#{__FILE__}:#{line}: 1 call"
|
134
|
-
codeline
|
135
|
-
assert_equal(text, Todonotes.
|
136
|
-
assert_equal(codeline, Todonotes.
|
141
|
+
codeline << "#{__FILE__}:#{line} (FixMe)"
|
142
|
+
assert_equal(text, Todonotes::TODONOTES.overview())
|
143
|
+
assert_equal(codeline, Todonotes::TODONOTES.codelines.keys)
|
144
|
+
#Check class methods
|
145
|
+
assert_equal(Todonotes.overview(), Todonotes::TODONOTES.overview())
|
146
|
+
assert_equal(Todonotes.codelines, Todonotes::TODONOTES.codelines)
|
147
|
+
end #test_overview()
|
137
148
|
|
149
|
+
def test_plural()
|
138
150
|
#check plural-s in calls
|
139
151
|
line = __LINE__; 2.times{ fixme('c') }
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
assert_equal(
|
152
|
+
assert_equal("List of ToDos/FixMes:\n#{__FILE__}:#{line}: 2 calls", Todonotes::TODONOTES.overview())
|
153
|
+
assert_equal(["#{__FILE__}:#{line} (FixMe)"], Todonotes::TODONOTES.codelines.keys)
|
154
|
+
#Check class methods
|
155
|
+
assert_equal(Todonotes.overview(), Todonotes::TODONOTES.overview())
|
156
|
+
assert_equal(Todonotes.codelines, Todonotes::TODONOTES.codelines)
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_overview_with_type()
|
160
|
+
|
161
|
+
line = __LINE__; fixme('a')
|
162
|
+
|
163
|
+
assert_equal("List of ToDos/FixMes:\n#{__FILE__}:#{line} (FixMe): 1 call",
|
164
|
+
Todonotes::TODONOTES.overview(:with_type)
|
165
|
+
)
|
166
|
+
#Check class methods
|
167
|
+
assert_equal(Todonotes.overview(), Todonotes::TODONOTES.overview())
|
168
|
+
assert_equal(Todonotes.codelines, Todonotes::TODONOTES.codelines)
|
169
|
+
|
144
170
|
end
|
171
|
+
def test_overview_with_type_description()
|
172
|
+
|
173
|
+
line = __LINE__; fixme('a')
|
174
|
+
|
175
|
+
assert_equal("List of ToDos/FixMes:\n#{__FILE__}:#{line} (FixMe): 1 call (a)",
|
176
|
+
Todonotes::TODONOTES.overview(:with_type, :with_shortdescription)
|
177
|
+
)
|
178
|
+
|
179
|
+
#Check class methods
|
180
|
+
assert_equal(Todonotes.overview(), Todonotes::TODONOTES.overview())
|
181
|
+
assert_equal(Todonotes.codelines, Todonotes::TODONOTES.codelines)
|
182
|
+
|
183
|
+
end
|
184
|
+
def test_overview_with_type_description_result()
|
185
|
+
|
186
|
+
line = __LINE__; fixme('a'){2}
|
187
|
+
|
188
|
+
assert_equal("List of ToDos/FixMes:\n#{__FILE__}:#{line} (FixMe): 1 call (a) = '2'",
|
189
|
+
Todonotes::TODONOTES.overview(:with_type, :with_shortdescription, :with_result)
|
190
|
+
)
|
191
|
+
|
192
|
+
#Check class methods
|
193
|
+
assert_equal(Todonotes.overview(), Todonotes::TODONOTES.overview())
|
194
|
+
assert_equal(Todonotes.codelines, Todonotes::TODONOTES.codelines)
|
195
|
+
|
196
|
+
end
|
145
197
|
end
|
146
198
|
|
147
199
|
class Test_log_with_file < Test::Unit::TestCase
|
@@ -157,21 +209,20 @@ class Test_log_with_file < Test::Unit::TestCase
|
|
157
209
|
end
|
158
210
|
def test_logfile()
|
159
211
|
assert_false(File.exist?(@@logfilename))
|
160
|
-
Todonotes.
|
161
|
-
assert_equal(@@logfilename, Todonotes.
|
212
|
+
Todonotes::TODONOTES.log2file(@@logfilename)
|
213
|
+
assert_equal(@@logfilename, Todonotes::TODONOTES.logger.outputters.last.filename)
|
162
214
|
assert_true(File.exist?(@@logfilename))
|
163
|
-
Todonotes.
|
164
|
-
Todonotes.
|
215
|
+
Todonotes::TODONOTES.logger.outputters.last.close #
|
216
|
+
Todonotes::TODONOTES.logger.outputters.pop #
|
165
217
|
end
|
166
218
|
def test_logfile_default()
|
167
219
|
assert_false(File.exist?(@@logfilename_default))
|
168
|
-
Todonotes.
|
169
|
-
assert_equal(@@logfilename_default, Todonotes.
|
220
|
+
Todonotes::TODONOTES.log2file() #no filename
|
221
|
+
assert_equal(@@logfilename_default, Todonotes::TODONOTES.logger.outputters.last.filename)
|
170
222
|
assert_true(File.exist?(@@logfilename_default))
|
171
|
-
Todonotes.
|
172
|
-
Todonotes.
|
223
|
+
Todonotes::TODONOTES.logger.outputters.last.close #
|
224
|
+
Todonotes::TODONOTES.logger.outputters.pop #
|
173
225
|
end
|
174
226
|
end
|
175
227
|
|
176
|
-
|
177
228
|
__END__
|
metadata
CHANGED
@@ -1,91 +1,81 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: todonotes
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 0
|
10
|
-
version: 0.1.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Knut Lickert
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-12-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: log4r
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
33
22
|
type: :runtime
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: ! 'todonotes.
|
31
|
+
|
32
|
+
Support programming by fixme/todo commands.
|
33
|
+
|
34
|
+
|
39
35
|
Gem based on a proposal in http://forum.ruby-portal.de/viewtopic.php?f=11&t=11957
|
40
36
|
|
37
|
+
'
|
41
38
|
email: knut@lickert.net
|
42
39
|
executables: []
|
43
|
-
|
44
40
|
extensions: []
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
- readme.rd
|
41
|
+
extra_rdoc_files:
|
42
|
+
- readme.rdoc
|
43
|
+
files:
|
44
|
+
- readme.rdoc
|
50
45
|
- lib/todonotes.rb
|
46
|
+
- lib/todonotes/todonotes.rb
|
47
|
+
- lib/todonotes/todo.rb
|
48
|
+
- lib/todonotes/kernel.rb
|
49
|
+
- lib/todonotes/log4r.rb
|
51
50
|
- examples/todonotes_how_to.rb
|
52
51
|
- examples/todonotes_prim.rb
|
53
52
|
- examples/todonotes_prim2.rb
|
54
53
|
- unittest/unittest_todonotes.rb
|
55
|
-
|
56
|
-
homepage:
|
54
|
+
homepage: http://rubypla.net/todonotes
|
57
55
|
licenses: []
|
58
|
-
|
59
56
|
post_install_message:
|
60
|
-
rdoc_options:
|
61
|
-
-
|
62
|
-
- readme.
|
63
|
-
require_paths:
|
57
|
+
rdoc_options:
|
58
|
+
- lib/**/*.rb
|
59
|
+
- --main readme.rdoc
|
60
|
+
require_paths:
|
64
61
|
- lib
|
65
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
63
|
none: false
|
67
|
-
requirements:
|
68
|
-
- -
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
|
71
|
-
|
72
|
-
- 0
|
73
|
-
version: "0"
|
74
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
69
|
none: false
|
76
|
-
requirements:
|
77
|
-
- -
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
|
80
|
-
segments:
|
81
|
-
- 0
|
82
|
-
version: "0"
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
83
74
|
requirements: []
|
84
|
-
|
85
75
|
rubyforge_project:
|
86
|
-
rubygems_version: 1.
|
76
|
+
rubygems_version: 1.8.24
|
87
77
|
signing_key:
|
88
78
|
specification_version: 3
|
89
79
|
summary: Support programming by todonotes/todo commands.
|
90
|
-
test_files:
|
80
|
+
test_files:
|
91
81
|
- unittest/unittest_todonotes.rb
|