vclog 1.1 → 1.2

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.
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