vclog 1.8.2 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +4 -3
- data/.yardopts +7 -0
- data/HISTORY.rdoc +207 -0
- data/README.rdoc +44 -27
- data/bin/vclog +4 -2
- data/bin/vclog-autotag +6 -0
- data/bin/vclog-bump +6 -0
- data/bin/vclog-formats +6 -0
- data/bin/vclog-version +6 -0
- data/lib/vclog.rb +1 -1
- data/lib/vclog.yml +58 -0
- data/lib/vclog/adapters.rb +2 -1
- data/lib/vclog/adapters/abstract.rb +87 -232
- data/lib/vclog/adapters/darcs.rb +72 -67
- data/lib/vclog/adapters/git.rb +166 -140
- data/lib/vclog/adapters/hg.rb +98 -62
- data/lib/vclog/adapters/svn.rb +116 -113
- data/lib/vclog/change.rb +110 -81
- data/lib/vclog/change_point.rb +77 -0
- data/lib/vclog/changelog.rb +58 -296
- data/lib/vclog/cli.rb +6 -70
- data/lib/vclog/cli/abstract.rb +64 -81
- data/lib/vclog/cli/autotag.rb +1 -3
- data/lib/vclog/cli/bump.rb +3 -4
- data/lib/vclog/cli/formats.rb +4 -4
- data/lib/vclog/cli/log.rb +86 -0
- data/lib/vclog/cli/version.rb +3 -3
- data/lib/vclog/{facets.rb → core_ext.rb} +0 -0
- data/lib/vclog/heuristics.rb +112 -38
- data/lib/vclog/heuristics/rule.rb +52 -12
- data/lib/vclog/heuristics/{label.rb → type.rb} +2 -2
- data/lib/vclog/history_file.rb +2 -2
- data/lib/vclog/metadata.rb +13 -1
- data/lib/vclog/release.rb +26 -12
- data/lib/vclog/repo.rb +191 -27
- data/lib/vclog/report.rb +187 -0
- data/lib/vclog/tag.rb +66 -39
- data/lib/vclog/templates/changelog.ansi.rb +9 -26
- data/lib/vclog/templates/changelog.atom.erb +3 -3
- data/lib/vclog/templates/changelog.gnu.rb +4 -11
- data/lib/vclog/templates/changelog.html.erb +11 -2
- data/lib/vclog/templates/changelog.markdown.rb +4 -4
- data/lib/vclog/templates/changelog.rdoc.rb +4 -4
- data/lib/vclog/templates/changelog.rss.erb +2 -6
- data/lib/vclog/templates/changelog.xml.erb +14 -2
- data/lib/vclog/templates/history.ansi.rb +10 -17
- data/lib/vclog/templates/history.atom.erb +4 -4
- data/lib/vclog/templates/history.gnu.rb +5 -7
- data/lib/vclog/templates/history.html.erb +11 -4
- data/lib/vclog/templates/history.json.rb +1 -1
- data/lib/vclog/templates/history.markdown.rb +5 -7
- data/lib/vclog/templates/history.rdoc.rb +5 -9
- data/lib/vclog/templates/history.rss.erb +3 -5
- data/lib/vclog/templates/history.xml.erb +15 -3
- data/lib/vclog/templates/history.yaml.rb +1 -1
- data/man/man1/vclog-autotag.1 +1 -1
- data/man/man1/vclog-autotag.1.html +1 -1
- data/man/man1/vclog-bump.1 +1 -1
- data/man/man1/vclog-bump.1.html +1 -1
- data/man/man1/vclog-version.1 +1 -1
- data/man/man1/vclog-version.1.html +1 -1
- data/man/man1/vclog.1 +25 -13
- data/man/man1/vclog.1.html +29 -20
- data/man/man1/vclog.1.ronn +31 -18
- data/test/unit/case_metadata.rb +1 -1
- metadata +48 -34
- data/lib/vclog/cli/changelog.rb +0 -33
- data/lib/vclog/cli/help.rb +0 -42
- data/lib/vclog/cli/history.rb +0 -39
- data/lib/vclog/formatter.rb +0 -123
- data/lib/vclog/history.rb +0 -131
- data/lib/vclog/kernel.rb +0 -12
- data/man/man1/vclog-changelog.1 +0 -47
- data/man/man1/vclog-changelog.1.html +0 -123
- data/man/man1/vclog-changelog.1.ronn +0 -39
- data/man/man1/vclog-history.1 +0 -44
- data/man/man1/vclog-history.1.html +0 -122
- data/man/man1/vclog-history.1.ronn +0 -38
data/lib/vclog/report.rb
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
#require 'ansi'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module VCLog
|
6
|
+
|
7
|
+
# The Report class acts a controller for outputing
|
8
|
+
# change log / release history.
|
9
|
+
#
|
10
|
+
class Report
|
11
|
+
|
12
|
+
#
|
13
|
+
# Directory of this file, so as to locate templates.
|
14
|
+
#
|
15
|
+
DIR = File.dirname(__FILE__)
|
16
|
+
|
17
|
+
#
|
18
|
+
# Instance of VCLog::Repo.
|
19
|
+
#
|
20
|
+
attr :repo
|
21
|
+
|
22
|
+
#
|
23
|
+
# OpenStruct of report options.
|
24
|
+
#
|
25
|
+
attr :options
|
26
|
+
|
27
|
+
#
|
28
|
+
# Setup new Reporter instance.
|
29
|
+
#
|
30
|
+
# @param [Repo] repo
|
31
|
+
# An instance of VCLog::Repo.
|
32
|
+
#
|
33
|
+
def initialize(repo, options)
|
34
|
+
@repo = repo
|
35
|
+
@options = case options
|
36
|
+
when Hash
|
37
|
+
OpenStruct.new(options)
|
38
|
+
else
|
39
|
+
options
|
40
|
+
end
|
41
|
+
|
42
|
+
@options.level ||= 0
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Returns a Changelog object.
|
47
|
+
#
|
48
|
+
def changelog
|
49
|
+
changes = options.point ? repo.changes : repo.change_points
|
50
|
+
ChangeLog.new(changes).above(options.level)
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Compute and return set of releases for +changelog+ changes.
|
55
|
+
#
|
56
|
+
def releases
|
57
|
+
repo.releases(changelog.changes)
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# User as given by the command line or from the repo.
|
62
|
+
#
|
63
|
+
def user
|
64
|
+
options.user || repo.user
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Email address as given on the command line or from the repo.
|
69
|
+
#
|
70
|
+
def email
|
71
|
+
options.email || repo.email
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Repo repository URL.
|
76
|
+
#
|
77
|
+
def repository
|
78
|
+
repo.repository
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Repository URL.
|
83
|
+
#
|
84
|
+
# @todo Ensure this is being provided.
|
85
|
+
#
|
86
|
+
def url
|
87
|
+
options.url || repo.repository
|
88
|
+
end
|
89
|
+
|
90
|
+
# TODO
|
91
|
+
def homepage
|
92
|
+
options.homepage
|
93
|
+
end
|
94
|
+
|
95
|
+
# TODO: Let the title be nil and the template can set a default if it needs to.
|
96
|
+
|
97
|
+
#
|
98
|
+
# Report title.
|
99
|
+
#
|
100
|
+
def title
|
101
|
+
return options.title if options.title
|
102
|
+
case options.type
|
103
|
+
when :history
|
104
|
+
"RELEASE HISTORY"
|
105
|
+
else
|
106
|
+
"CHANGELOG"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# NOTE: ERBs trim_mode is broken --it removes an extra space.
|
111
|
+
# So we can't use it for plain text templates.
|
112
|
+
|
113
|
+
#
|
114
|
+
# Print report.
|
115
|
+
#
|
116
|
+
def print
|
117
|
+
options.type ||= 'changelog'
|
118
|
+
options.format ||= 'ansi'
|
119
|
+
|
120
|
+
require_formatter(options.format)
|
121
|
+
|
122
|
+
tmp_file = Dir[File.join(DIR, 'templates', "#{options.type}.#{options.format}.{erb,rb}")].first
|
123
|
+
|
124
|
+
tmp = File.read(tmp_file)
|
125
|
+
|
126
|
+
case File.extname(tmp_file)
|
127
|
+
when '.rb'
|
128
|
+
eval(tmp, binding, tmp_file)
|
129
|
+
when '.erb'
|
130
|
+
erb = ERB.new(tmp, nil, '<>')
|
131
|
+
erb.result(binding)
|
132
|
+
else
|
133
|
+
raise "unrecognized template - #{tmp_file}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
#
|
140
|
+
# Depending on the format special libraries may by required.
|
141
|
+
#
|
142
|
+
def require_formatter(format)
|
143
|
+
case format.to_s
|
144
|
+
when 'yaml'
|
145
|
+
require 'yaml'
|
146
|
+
when 'json'
|
147
|
+
require 'json'
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
#
|
152
|
+
# HTML escape.
|
153
|
+
#
|
154
|
+
def h(input)
|
155
|
+
result = input.to_s.dup
|
156
|
+
result.gsub!("&", "&")
|
157
|
+
result.gsub!("<", "<")
|
158
|
+
result.gsub!(">", ">")
|
159
|
+
result.gsub!("'", "'")
|
160
|
+
#result.gsub!("@", "&at;")
|
161
|
+
result.gsub!("\"", """)
|
162
|
+
return result
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# Convert from RDoc to HTML.
|
167
|
+
#
|
168
|
+
def r(input)
|
169
|
+
rdoc.convert(input)
|
170
|
+
end
|
171
|
+
|
172
|
+
#
|
173
|
+
# RDoc converter.
|
174
|
+
#
|
175
|
+
# @return [RDoc::Markup::ToHtml] rdoc markup HTML converter.
|
176
|
+
#
|
177
|
+
def rdoc
|
178
|
+
@_rdoc ||= (
|
179
|
+
gem 'rdoc' rescue nil # to ensure latest version
|
180
|
+
require 'rdoc'
|
181
|
+
RDoc::Markup::ToHtml.new
|
182
|
+
)
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
data/lib/vclog/tag.rb
CHANGED
@@ -1,27 +1,68 @@
|
|
1
1
|
module VCLog
|
2
2
|
|
3
|
+
#
|
3
4
|
class Tag
|
5
|
+
|
6
|
+
#
|
7
|
+
# Tag's commit id.
|
8
|
+
#
|
9
|
+
attr_accessor :id
|
10
|
+
|
11
|
+
#
|
12
|
+
# Tag name, which in this case is typically a version stamp.
|
13
|
+
#
|
4
14
|
attr_accessor :name
|
15
|
+
|
16
|
+
#
|
17
|
+
# Date tag was made.
|
18
|
+
#
|
5
19
|
attr_accessor :date
|
20
|
+
|
21
|
+
#
|
22
|
+
# Creator to the tag.
|
23
|
+
#
|
6
24
|
attr_accessor :author
|
25
|
+
|
26
|
+
#
|
27
|
+
# Tag message.
|
28
|
+
#
|
7
29
|
attr_accessor :message
|
8
30
|
|
31
|
+
#
|
32
|
+
# Last commit before Tag.
|
33
|
+
#
|
9
34
|
attr_accessor :commit
|
10
35
|
|
36
|
+
#
|
37
|
+
# @todo Hg is using this at the moment but it really shouldn't be here,
|
38
|
+
# since it is take care of by `commit.files`.
|
39
|
+
#
|
40
|
+
attr_accessor :files
|
41
|
+
|
42
|
+
#
|
43
|
+
# Setup new Tag intsance.
|
44
|
+
#
|
45
|
+
# If `:commit` is not provided, it is assume that the underlying SCM
|
46
|
+
# simply creates tags as references to a commit. That is to say the tag
|
47
|
+
# information and the commit information are one and the same. This is
|
48
|
+
# the case for Hg, but not for Git, for instance.
|
11
49
|
#
|
12
50
|
def initialize(data={})
|
13
|
-
@commit = Change.new
|
51
|
+
@commit = data.delete(:commit) || Change.new(data)
|
52
|
+
|
14
53
|
data.each do |k,v|
|
15
54
|
__send__("#{k}=", v)
|
16
55
|
end
|
17
56
|
end
|
18
57
|
|
58
|
+
#
|
59
|
+
# Set the tag name.
|
19
60
|
#
|
20
61
|
def name=(name)
|
21
62
|
@name = (name || 'HEAD').strip
|
22
63
|
end
|
23
64
|
|
24
|
-
#
|
65
|
+
# Alias for +name+ attribute.
|
25
66
|
alias_method :label, :name
|
26
67
|
alias_method :label=, :name=
|
27
68
|
|
@@ -29,87 +70,73 @@ module VCLog
|
|
29
70
|
alias_method :tag, :name
|
30
71
|
alias_method :tag=, :name=
|
31
72
|
|
32
|
-
#
|
73
|
+
# Set author name, stripping white space.
|
33
74
|
def author=(author)
|
34
75
|
@author = author.to_s.strip
|
35
76
|
end
|
36
77
|
|
78
|
+
# Alias for +author+ attribute.
|
37
79
|
alias_method :tagger, :author
|
38
80
|
alias_method :tagger=, :author=
|
39
81
|
|
82
|
+
# Alias for +author+ attribute.
|
40
83
|
alias_method :who, :author
|
41
84
|
alias_method :who=, :author=
|
42
85
|
|
86
|
+
#
|
87
|
+
# Set the tag date, converting +date+ to a Time object.
|
43
88
|
#
|
44
89
|
def date=(date)
|
45
90
|
@date = parse_date(date)
|
46
91
|
end
|
47
92
|
|
93
|
+
#
|
94
|
+
# Set the tag message.
|
48
95
|
#
|
49
96
|
def message=(msg)
|
50
97
|
@message = msg.strip
|
51
98
|
end
|
52
99
|
|
53
|
-
alias_method :msg, :message
|
54
|
-
alias_method :msg=, :message=
|
55
|
-
|
56
|
-
|
57
|
-
#
|
58
|
-
def commit_id
|
59
|
-
@commit.id
|
60
|
-
end
|
61
|
-
|
62
100
|
#
|
63
|
-
|
64
|
-
@commit.id = id
|
65
|
-
end
|
66
|
-
|
67
|
-
#
|
68
|
-
alias_method :id, :commit_id
|
69
|
-
alias_method :id=, :commit_id=
|
70
|
-
|
101
|
+
# Alias for +message+.
|
71
102
|
#
|
72
|
-
alias_method :
|
73
|
-
alias_method :
|
74
|
-
|
75
|
-
#
|
76
|
-
def commit_date
|
77
|
-
@commit.date ||= date
|
78
|
-
end
|
79
|
-
|
80
|
-
#
|
81
|
-
def commit_date=(date)
|
82
|
-
@commit.date = date
|
83
|
-
end
|
103
|
+
alias_method :msg, :message
|
104
|
+
alias_method :msg=, :message=
|
84
105
|
|
85
106
|
#
|
86
|
-
|
87
|
-
to_h.to_json
|
88
|
-
end
|
89
|
-
|
107
|
+
# Convert to Hash.
|
90
108
|
#
|
91
109
|
def to_h
|
92
110
|
{
|
93
111
|
'name' => name,
|
94
112
|
'date' => date,
|
95
113
|
'author' => author,
|
96
|
-
'message' => message
|
114
|
+
'message' => message,
|
115
|
+
'commit' => commit.to_h
|
97
116
|
}
|
98
117
|
end
|
99
118
|
|
119
|
+
#
|
120
|
+
# Inspection string for Tag.
|
100
121
|
#
|
101
122
|
def inspect
|
102
|
-
|
123
|
+
dstr = date ? date.strftime('%Y-%m-%d %H:%M:%S') : '(date?)'
|
124
|
+
"<Tag #{name} #{dstr}>"
|
103
125
|
end
|
104
126
|
|
127
|
+
#
|
105
128
|
# Normal tag order is the reverse typical sorts.
|
129
|
+
#
|
106
130
|
def <=>(other)
|
107
131
|
return -1 if name == 'HEAD'
|
108
132
|
other.name <=> name
|
109
133
|
end
|
110
134
|
|
111
|
-
|
135
|
+
private
|
112
136
|
|
137
|
+
#
|
138
|
+
#
|
139
|
+
#
|
113
140
|
def parse_date(date)
|
114
141
|
case date
|
115
142
|
when Time
|
@@ -13,34 +13,17 @@ changelog.by_date.each do |date, date_changes|
|
|
13
13
|
author_changes.sort!{|a,b| b.level <=> a.level}
|
14
14
|
|
15
15
|
author_changes.each do |entry|
|
16
|
+
msg = entry.to_s(:summary=>!options.detail)
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
line << " <#{ entry.type }>"
|
21
|
-
end
|
22
|
-
|
23
|
-
if options.revision
|
24
|
-
line << " (##{entry.revision})"
|
25
|
-
end
|
26
|
-
|
27
|
-
case entry.level
|
28
|
-
when 1
|
29
|
-
line = line.ansi(:yellow)
|
30
|
-
when 0
|
31
|
-
line = line.ansi(:green)
|
32
|
-
when -1
|
33
|
-
line = line.ansi(:cyan)
|
34
|
-
else
|
35
|
-
if entry.level > 1
|
36
|
-
line = line.ansi(:red)
|
37
|
-
else
|
38
|
-
line = line.ansi(:blue)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
out << " * " + line
|
18
|
+
#if !options.summary && entry.type
|
19
|
+
# msg << " [#{ entry.type }]"
|
20
|
+
#end
|
43
21
|
|
22
|
+
msg = msg.ansi(*entry.color) unless entry.color.empty?
|
23
|
+
|
24
|
+
msg << "\n(##{entry.id})" if options.reference
|
25
|
+
|
26
|
+
out << msg.tabto(4).sub(' ',' * ')
|
44
27
|
end
|
45
28
|
|
46
29
|
out << ""
|
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
<% if homepage %><link href="<%= homepage %>" /><% end %>
|
10
10
|
|
11
|
-
<id><% if
|
11
|
+
<id><% if repo.uuid %>urn:uuid:<%= repo.uuid %><% else %><%= repo.repository %><% end %></id>
|
12
12
|
|
13
13
|
<updated><%= Time.now.xmlschema %></updated>
|
14
14
|
|
@@ -24,9 +24,9 @@
|
|
24
24
|
|
25
25
|
<entry>
|
26
26
|
|
27
|
-
<title><%= h entry.
|
27
|
+
<title><%= h entry.summary %></title>
|
28
28
|
|
29
|
-
<id><%= url %>#<%= entry.
|
29
|
+
<id><%= url %>#<%= entry.id %></id>
|
30
30
|
|
31
31
|
<author><%= entry.author %></author>
|
32
32
|
|
@@ -5,25 +5,18 @@ out << "#{title}\n" if title
|
|
5
5
|
changelog.by_date.each do |date, date_changes|
|
6
6
|
|
7
7
|
date_changes.by_author.each do |author, author_changes|
|
8
|
-
|
9
8
|
out << "#{ date } #{ author }\n"
|
10
9
|
|
11
10
|
author_changes.each do |entry|
|
11
|
+
msg = entry.to_s(:summary=>!options.detail)
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
if options.extra && entry.type
|
16
|
-
out.last << " <#{ entry.type }>"
|
17
|
-
end
|
18
|
-
|
19
|
-
if options.revision
|
20
|
-
out.last << "(##{entry.revision})"
|
21
|
-
end
|
13
|
+
#msg << " [#{entry.type}]" if entry.type && !options.summary
|
14
|
+
msg << "\n(##{entry.id})" if options.reference
|
22
15
|
|
16
|
+
out << msg.tabto(8).sub(' ',' * ')
|
23
17
|
end
|
24
18
|
|
25
19
|
out << ""
|
26
|
-
|
27
20
|
end
|
28
21
|
|
29
22
|
end
|