vclog 1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY.md CHANGED
@@ -1,10 +1,30 @@
1
1
  # RELEASE HISTORY
2
2
 
3
+ ## 1.2 / 2009-10-26
4
+
5
+ Version 1.2 overhuals the internals so that History
6
+ output is based on scm tags, not on a pre-existing history file.
7
+ This is really the proper way to go about it and those
8
+ who use it will, I think, be happily surprised at how it
9
+ promotes good practices for the maintenance of History files.
10
+ This overhaul led to substantial changes in the command-line
11
+ interface.
12
+
13
+ Changes:
14
+
15
+ * 2 Major Enhancements
16
+
17
+ * Rewrote History class.
18
+ * Changed command-line interface.
19
+
20
+
3
21
  ## 1.1 / 2009-10-23
4
22
 
5
23
  This release adds yaml and json formats an improves
6
24
  the command.
7
25
 
26
+ Changes:
27
+
8
28
  * 2 Major Enhancements
9
29
 
10
30
  * Added YAML format.
data/MANIFEST CHANGED
@@ -5,9 +5,13 @@ README
5
5
  TODO
6
6
  bin/vclog
7
7
  lib/vclog
8
+ lib/vclog/change.rb
8
9
  lib/vclog/changelog.rb
9
- lib/vclog/command.rb
10
+ lib/vclog/cli.rb
10
11
  lib/vclog/facets.rb
12
+ lib/vclog/history.rb
13
+ lib/vclog/release.rb
14
+ lib/vclog/tag.rb
11
15
  lib/vclog/vcs
12
16
  lib/vclog/vcs.rb
13
17
  lib/vclog/vcs/darcs.rb
data/TODO CHANGED
@@ -1,5 +1,17 @@
1
1
  = TODO
2
2
 
3
+ == Support Markdown and RDoc release output styles
4
+
5
+ Right now its all RDoc.
6
+
7
+ == Imporved parsing flexability
8
+
9
+ In general parsing hueristics need to be imporved. Some specifics:
10
+
11
+ * Need to support relase comments.
12
+ * Need to recognize "Changes:" marker
13
+
14
+
3
15
  == Typed option needs work
4
16
 
5
17
  It produced no results sometimes. Fix or deprecate.
data/bin/vclog CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- load 'vclog/command'
2
+ load 'vclog/cli'
3
3
  VCLog.run
4
4
 
@@ -0,0 +1,108 @@
1
+ module VCLog
2
+
3
+ # = Change Log Entry class
4
+ #
5
+ class Change
6
+
7
+ include Comparable
8
+
9
+ attr_accessor :author
10
+ attr_accessor :date
11
+ attr_accessor :revision
12
+ attr_accessor :message
13
+ attr_accessor :type
14
+
15
+ #
16
+ def initialize(rev, date, author, message, type=nil)
17
+ self.revision = rev #opts[:revison] || opts[:rev]
18
+ self.date = date #opts[:date] || opts[:when]
19
+ self.author = author #opts[:author] || opts[:who]
20
+ self.type = type #opts[:type]
21
+ self.message = message #opts[:message] || opts[:msg]
22
+ end
23
+
24
+ #
25
+ def author=(author)
26
+ @author = author.strip
27
+ end
28
+
29
+ def message=(note)
30
+ @message = note.strip
31
+ end
32
+
33
+ #def clean_type(type)
34
+ # case type.to_s
35
+ # when 'maj', 'major' then :major
36
+ # when 'min', 'minor' then :minor
37
+ # when 'bug' then :bug
38
+ # when '' then :other
39
+ # else
40
+ # type.to_sym
41
+ # end
42
+ #end
43
+
44
+ #
45
+ def type_phrase
46
+ case type.to_s
47
+ when 'maj', 'major'
48
+ 'Major Enhancements'
49
+ when 'min', 'minor'
50
+ 'Minor Enhancements'
51
+ when 'bug'
52
+ 'Bug Fixes'
53
+ when ''
54
+ 'General Enhancements'
55
+ when '-'
56
+ 'Administrative Changes'
57
+ else
58
+ "#{type.capitalize} Enhancements"
59
+ end
60
+ end
61
+
62
+ #
63
+ def type_number
64
+ case type.to_s.downcase
65
+ when 'maj', 'major'
66
+ 0
67
+ when 'min', 'minor'
68
+ 1
69
+ when 'bug'
70
+ 2
71
+ when ''
72
+ 4
73
+ when '-'
74
+ 5
75
+ else # other
76
+ 3
77
+ end
78
+ end
79
+
80
+ #
81
+ def <=>(other)
82
+ other.date <=> date
83
+ end
84
+
85
+ def inspect
86
+ "#<Change:#{object_id} #{date}>"
87
+ end
88
+
89
+ def to_h
90
+ { 'author' => @author,
91
+ 'date' => @date,
92
+ 'revision' => @revison,
93
+ 'message' => @message,
94
+ 'type' => @type
95
+ }
96
+ end
97
+
98
+ def to_json
99
+ to_h.to_json
100
+ end
101
+
102
+ def to_yaml(*args)
103
+ to_h.to_yaml(*args)
104
+ end
105
+
106
+ end #class Entry
107
+
108
+ end
@@ -1,6 +1,7 @@
1
1
  module VCLog
2
2
 
3
3
  require 'vclog/facets'
4
+ require 'vclog/change'
4
5
 
5
6
  # Supports output formats:
6
7
  #
@@ -10,7 +11,7 @@ module VCLog
10
11
  # json
11
12
  # text
12
13
  #
13
- class Changelog
14
+ class ChangeLog
14
15
 
15
16
  include Enumerable
16
17
 
@@ -18,31 +19,55 @@ module VCLog
18
19
 
19
20
  attr :changes
20
21
 
22
+ attr_accessor :marker
23
+
24
+ attr_accessor :title
25
+
26
+ # Include revision id?
27
+ attr_accessor :rev_id
28
+
29
+ #
21
30
  def initialize(changes=nil)
22
- @changes = changes || []
31
+ @changes = []
32
+ @marker = "#"
33
+ @title = "CHANGE LOG"
34
+ @rev_id = false
35
+
36
+ @changes = changes if changes
23
37
  end
24
38
 
25
- def change(date, who, rev, note)
26
- note, type = *split_note(note)
27
- note = note.gsub(/^\s*?\n/m,'') # remove blank lines
28
- @changes << Entry.new(:when=>date, :who=>who, :rev=>rev, :type=>type, :msg=>note)
39
+ #def changes=(changes)
40
+ # @changes = []
41
+ # changes.each do |change|
42
+ # case change
43
+ # when Change
44
+ # @changes << change
45
+ # else
46
+ # @changes << Change.new(*change)
47
+ # end
48
+ # end
49
+ #end
50
+
51
+ # Add a change entry to the log.
52
+ def change(rev, date, who, note, type=nil)
53
+ @changes << Change.new(rev, date, who, note, type)
29
54
  end
30
55
 
31
- def each(&block) ; @changes.each(&block) ; end
32
- def empty? ; @changes.empty? ; end
33
- def size ; @changes.size ; end
56
+ def each(&block) ; changes.each(&block) ; end
57
+ def empty? ; changes.empty? ; end
58
+ def size ; changes.size ; end
34
59
 
35
60
  #
36
61
  def <<(entry)
37
- raise unless Entry===entry
62
+ raise unless Change===entry
38
63
  @changes << entry
39
64
  end
40
65
 
41
66
  # Return a new changelog with entries that have a specified type.
42
67
  # TODO: Be able to specify which types to include or omit.
43
- def typed
44
- self.class.new(changes.select{ |e| e.type })
45
- end
68
+ #def typed
69
+ # self.class.new(changes.select{ |e| e.type })
70
+ #end
46
71
 
47
72
  # Return a new changelog with entries occuring after the
48
73
  # given date limit.
@@ -58,8 +83,6 @@ module VCLog
58
83
  self.class.new(before)
59
84
  end
60
85
 
61
- #
62
-
63
86
  #
64
87
  def by_type
65
88
  mapped = {}
@@ -105,18 +128,18 @@ module VCLog
105
128
  # Output Formats #
106
129
  ##################
107
130
 
108
- def format_yaml
131
+ def to_yaml
109
132
  require 'yaml'
110
133
  changes.to_yaml
111
134
  end
112
135
 
113
- def format_json
136
+ def to_json
114
137
  require 'json'
115
138
  changes.to_json
116
139
  end
117
140
 
118
141
  #
119
- def format_gnu
142
+ def to_gnu(rev=false)
120
143
  x = []
121
144
  by_date.each do |date, date_changes|
122
145
  date_changes.by_author.each do |author, author_changes|
@@ -128,6 +151,7 @@ module VCLog
128
151
  else
129
152
  msg = "#{entry.message}".tabto(10)
130
153
  end
154
+ msg << " (#{entry.revision})" if rev
131
155
  msg[8] = '*'
132
156
  x << msg
133
157
  end
@@ -138,11 +162,11 @@ module VCLog
138
162
  end
139
163
 
140
164
  #
141
- alias_method :to_s, :format_gnu
165
+ alias_method :to_s, :to_gnu
142
166
 
143
167
  # Create an XML formated changelog.
144
168
  # +xsl+ reference defaults to 'log.xsl'
145
- def format_xml(xsl=nil)
169
+ def to_xml(xsl=nil)
146
170
  xsl = 'log.xsl' if xsl.nil?
147
171
  x = []
148
172
  x << %[<?xml version="1.0"?>]
@@ -152,7 +176,7 @@ module VCLog
152
176
  x << %[<entry>]
153
177
  x << %[ <date>#{entry.date}</date>]
154
178
  x << %[ <author>#{escxml(entry.author)}</author>]
155
- x << %[ <revison>#{escxml(entry.revison)}</revison>]
179
+ x << %[ <revision>#{escxml(entry.revision)}</revision>]
156
180
  x << %[ <type>#{escxml(entry.type)}</type>]
157
181
  x << %[ <message>#{escxml(entry.message)}</message>]
158
182
  x << %[</entry>]
@@ -163,12 +187,12 @@ module VCLog
163
187
 
164
188
  # Create an HTML formated changelog.
165
189
  # +css+ reference defaults to 'log.css'
166
- def format_html(css=nil)
190
+ def to_html(css=nil)
167
191
  css = 'log.css' if css.nil?
168
192
  x = []
169
193
  x << %[<html>]
170
194
  x << %[<head>]
171
- x << %[ <title>Changelog</title>]
195
+ x << %[ <title>ChangeLog</title>]
172
196
  x << %[ <style>]
173
197
  x << %[ body{font-family: sans-serif;}]
174
198
  x << %[ #changelog{width:800px;margin:0 auto;}]
@@ -176,7 +200,7 @@ module VCLog
176
200
  x << %[ .date{font-weight: bold; color: gray; float: left; padding: 0 5px;}]
177
201
  x << %[ .author{color: red;}]
178
202
  x << %[ .message{padding: 5 0; font-weight: bold;}]
179
- x << %[ .revison{font-size: 0.8em;}]
203
+ x << %[ .revision{font-size: 0.8em;}]
180
204
  x << %[ </style>]
181
205
  x << %[ <link rel="stylesheet" href="#{css}" type="text/css">] if css
182
206
  x << %[</head>]
@@ -190,7 +214,7 @@ module VCLog
190
214
  x << %[ <div class="author">#{escxml(entry.author)}</div>]
191
215
  x << %[ <div class="type">#{escxml(entry.type)}</div>]
192
216
  x << %[ <div class="message">#{escxml(entry.message)}</div>]
193
- x << %[ <div class="revison">##{escxml(entry.revison)}</div>]
217
+ x << %[ <div class="revision">##{escxml(entry.revision)}</div>]
194
218
  x << %[ </li>]
195
219
  end
196
220
  x << %[ </ul>]
@@ -200,6 +224,76 @@ module VCLog
200
224
  return x.join("\n")
201
225
  end
202
226
 
227
+
228
+ # Translate history into a Markdown formatted document.
229
+ def to_markdown(rev=false)
230
+ to_markup('#', rev)
231
+ end
232
+
233
+ # Translate history into a RDoc formatted document.
234
+ def to_rdoc(rev=false)
235
+ to_markup('=', rev)
236
+ end
237
+
238
+ #
239
+ def to_markup(marker, rev=false)
240
+
241
+ x = []
242
+ by_date.each do |date, date_changes|
243
+ date_changes.by_author.each do |author, author_changes|
244
+ x << "#{marker}#{marker} #{date} #{author}\n"
245
+ x << to_markup_changes(author_changes, rev)
246
+ end
247
+ x << ""
248
+ end
249
+ marker + " #{title}\n\n" + x.join("\n")
250
+ end
251
+
252
+ private
253
+
254
+ #
255
+ def to_markup_changes(changes, rev=false)
256
+ groups = changes.group_by{ |e| e.type_number }
257
+ string = ""
258
+ 5.times do |n|
259
+ entries = groups[n]
260
+ next if !entries
261
+ next if entries.empty?
262
+ string << "* #{entries.size} #{entries[0].type_phrase}\n\n"
263
+ entries.sort!{|a,b| a.date <=> b.date }
264
+ entries.each do |entry|
265
+ #string << "#{marker}#{marker} #{entry.date} #{entry.author}\n\n" # no email :(
266
+ if rev
267
+ text = "#{entry.message} (##{entry.revision})"
268
+ else
269
+ text = "#{entry.message}"
270
+ end
271
+ text = text.tabto(6)
272
+ text[4] = '*'
273
+ #entry = entry.join(' ').tabto(6)
274
+ #entry[4] = '*'
275
+ string << text
276
+ string << "\n"
277
+ end
278
+ string << "\n"
279
+ end
280
+ string.chomp("\n")
281
+ end
282
+
283
+ end
284
+
285
+ end
286
+
287
+
288
+
289
+
290
+
291
+
292
+
293
+
294
+
295
+
296
+ =begin
203
297
  #
204
298
  def format_rel(file, current_version=nil, current_release=nil, rev=false)
205
299
  log = []
@@ -249,11 +343,11 @@ module VCLog
249
343
  end
250
344
  reltext = changes.format_rel_types(rev)
251
345
  unless reltext.strip.empty?
252
- log << "== #{lt_vers} / #{lt_date.strftime('%Y-%m-%d')}\n\n#{reltext}"
346
+ log << "#{marker} #{lt_vers} / #{lt_date.strftime('%Y-%m-%d')}\n\n#{reltext}"
253
347
  end
254
348
  end
255
349
  # reverse log order and make into document
256
- log.reverse.join("\n")
350
+ marker[0,1] + " #{title}\n\n" + log.reverse.join("\n")
257
351
  end
258
352
 
259
353
  #
@@ -269,7 +363,7 @@ module VCLog
269
363
  entries.each do |entry|
270
364
  #string << "== #{date} #{who}\n\n" # no email :(
271
365
  if rev
272
- text = "#{entry.message} (##{entry.revison})"
366
+ text = "#{entry.message} (##{entry.revision})"
273
367
  else
274
368
  text = "#{entry.message}"
275
369
  end
@@ -289,20 +383,23 @@ module VCLog
289
383
  def releases(file)
290
384
  return [] unless file
291
385
  clog = File.read(file)
292
- tags = clog.scan(/^==(.*?)$/)
386
+ tags = clog.scan(/^(==|##)(.*?)$/)
293
387
  rels = tags.collect do |t|
294
- parse_version_tag(t[0])
388
+ parse_version_tag(t[1])
295
389
  end
390
+ @marker = tags[0][0]
296
391
  return rels
297
392
  end
298
393
 
299
394
  #
300
395
  def parse_version_tag(tag)
301
396
  version, date = *tag.split('/')
302
- version, date = version.sub(/^\=+\s*/,'').strip, date.strip
397
+ version, date = version.strip, date.strip
303
398
  return version, date
304
399
  end
400
+ =end
305
401
 
402
+ =begin
306
403
  ###################
307
404
  # Save Chaqngelog #
308
405
  ###################
@@ -311,18 +408,18 @@ module VCLog
311
408
  def save(file, format=:gnu, *args)
312
409
  case format.to_sym
313
410
  when :xml
314
- text = format_xml
315
- save_xsl(file)
411
+ text = to_xml
412
+ #save_xsl(file)
316
413
  when :html
317
- text = format_html(*args)
414
+ text = to_html(*args)
318
415
  when :rel
319
- text = format_rel(file, *args)
416
+ text = to_rel(file, *args)
320
417
  when :yaml
321
- text = format_yaml(file)
418
+ text = to_yaml(file)
322
419
  when :json
323
- text = format_json(file)
420
+ text = to_json(file)
324
421
  else
325
- text = format_gnu
422
+ text = to_gnu
326
423
  end
327
424
 
328
425
  FileUtils.mkdir_p(File.dirname(file))
@@ -363,112 +460,6 @@ module VCLog
363
460
  end
364
461
  end
365
462
 
366
- # Looks for a "[type]" indicator at the end of the message.
367
- def split_note(note)
368
- note = note.strip
369
- if md = /\A.*?\[(.*?)\]\s*$/.match(note)
370
- t = md[1].strip.downcase
371
- n = note.sub(/\[#{md[1]}\]\s*$/, "")
372
- else
373
- n, t = note, nil
374
- end
375
- return n, t
376
- end
377
-
378
- # = Change Log Entry class
379
- class Entry
380
- include Comparable
381
-
382
- attr_accessor :author
383
- attr_accessor :date
384
- attr_accessor :revison
385
- attr_accessor :message
386
- attr_accessor :type
387
-
388
- def initialize(opts={})
389
- @author = (opts[:author] || opts[:who]).strip
390
- @date = opts[:date] || opts[:when]
391
- @revison = opts[:revison] || opts[:rev]
392
- @message = opts[:message] || opts[:msg]
393
- @type = opts[:type]
394
- end
395
-
396
- #def clean_type(type)
397
- # case type.to_s
398
- # when 'maj', 'major' then :major
399
- # when 'min', 'minor' then :minor
400
- # when 'bug' then :bug
401
- # when '' then :other
402
- # else
403
- # type.to_sym
404
- # end
405
- #end
406
-
407
- #
408
- def type_phrase
409
- case type.to_s
410
- when 'maj', 'major'
411
- 'Major Enhancements'
412
- when 'min', 'minor'
413
- 'Minor Enhancements'
414
- when 'bug'
415
- 'Bug Fixes'
416
- when ''
417
- 'General Enhancements'
418
- when '-'
419
- 'Administrative Changes'
420
- else
421
- "#{type.capitalize} Enhancements"
422
- end
423
- end
424
-
425
- #
426
- def type_number
427
- case type.to_s.downcase
428
- when 'maj', 'major'
429
- 0
430
- when 'min', 'minor'
431
- 1
432
- when 'bug'
433
- 2
434
- when ''
435
- 4
436
- when '-'
437
- 5
438
- else # other
439
- 3
440
- end
441
- end
442
-
443
- #
444
- def <=>(other)
445
- other.date <=> date
446
- end
447
-
448
- def inspect
449
- "#<Entry:#{object_id} #{date}>"
450
- end
451
-
452
- def to_h
453
- { 'author' => @author,
454
- 'date' => @date,
455
- 'revision' => @revison,
456
- 'message' => @message,
457
- 'type' => @type
458
- }
459
- end
460
-
461
- def to_json
462
- to_h.to_json
463
- end
464
-
465
- def to_yaml(*args)
466
- to_h.to_yaml(*args)
467
- end
468
-
469
- end #class Entry
470
-
471
- end
472
463
 
473
464
  DEFAULT_LOG_XSL = <<-END.tabto(0)
474
465
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
@@ -505,6 +496,5 @@ module VCLog
505
496
 
506
497
  </xsl:stylesheet>
507
498
  END
508
-
509
- end
499
+ =end
510
500