rubycut-vclog 1.9.4
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/.yardopts +7 -0
- data/History.md +249 -0
- data/License.txt +23 -0
- data/README.md +133 -0
- data/bin/vclog +6 -0
- data/bin/vclog-autotag +6 -0
- data/bin/vclog-bump +6 -0
- data/bin/vclog-formats +6 -0
- data/bin/vclog-news +6 -0
- data/bin/vclog-version +6 -0
- data/lib/vclog.rb +6 -0
- data/lib/vclog.yml +68 -0
- data/lib/vclog/adapters.rb +12 -0
- data/lib/vclog/adapters/abstract.rb +131 -0
- data/lib/vclog/adapters/darcs.rb +93 -0
- data/lib/vclog/adapters/git.rb +190 -0
- data/lib/vclog/adapters/hg.rb +129 -0
- data/lib/vclog/adapters/svn.rb +155 -0
- data/lib/vclog/change.rb +207 -0
- data/lib/vclog/change_point.rb +77 -0
- data/lib/vclog/changelog.rb +233 -0
- data/lib/vclog/cli.rb +8 -0
- data/lib/vclog/cli/abstract.rb +92 -0
- data/lib/vclog/cli/autotag.rb +36 -0
- data/lib/vclog/cli/bump.rb +29 -0
- data/lib/vclog/cli/formats.rb +28 -0
- data/lib/vclog/cli/log.rb +86 -0
- data/lib/vclog/cli/news.rb +29 -0
- data/lib/vclog/cli/version.rb +30 -0
- data/lib/vclog/config.rb +143 -0
- data/lib/vclog/core_ext.rb +11 -0
- data/lib/vclog/heuristics.rb +192 -0
- data/lib/vclog/heuristics/rule.rb +73 -0
- data/lib/vclog/heuristics/type.rb +29 -0
- data/lib/vclog/history_file.rb +69 -0
- data/lib/vclog/metadata.rb +16 -0
- data/lib/vclog/rc.rb +9 -0
- data/lib/vclog/release.rb +67 -0
- data/lib/vclog/repo.rb +298 -0
- data/lib/vclog/report.rb +200 -0
- data/lib/vclog/tag.rb +151 -0
- data/lib/vclog/templates/changelog.ansi.rb +35 -0
- data/lib/vclog/templates/changelog.atom.erb +52 -0
- data/lib/vclog/templates/changelog.gnu.rb +24 -0
- data/lib/vclog/templates/changelog.html.erb +49 -0
- data/lib/vclog/templates/changelog.json.rb +1 -0
- data/lib/vclog/templates/changelog.markdown.rb +30 -0
- data/lib/vclog/templates/changelog.rdoc.rb +30 -0
- data/lib/vclog/templates/changelog.rss.erb +54 -0
- data/lib/vclog/templates/changelog.xml.erb +28 -0
- data/lib/vclog/templates/changelog.xsl +34 -0
- data/lib/vclog/templates/changelog.yaml.rb +1 -0
- data/lib/vclog/templates/history.ansi.rb +57 -0
- data/lib/vclog/templates/history.atom.erb +84 -0
- data/lib/vclog/templates/history.gnu.rb +39 -0
- data/lib/vclog/templates/history.html.erb +60 -0
- data/lib/vclog/templates/history.json.rb +1 -0
- data/lib/vclog/templates/history.markdown.rb +38 -0
- data/lib/vclog/templates/history.rdoc.rb +36 -0
- data/lib/vclog/templates/history.rss.erb +84 -0
- data/lib/vclog/templates/history.xml.erb +43 -0
- data/lib/vclog/templates/history.yaml.rb +1 -0
- data/man/man1/index.txt +9 -0
- data/man/man1/vclog-autotag.1.ronn +29 -0
- data/man/man1/vclog-bump.1.ronn +21 -0
- data/man/man1/vclog-news.1.ronn +25 -0
- data/man/man1/vclog-version.1.ronn +14 -0
- data/man/man1/vclog.1.ronn +49 -0
- data/spec/feature_git_changes.rb +58 -0
- data/spec/feature_git_history.rb +58 -0
- data/spec/feature_hg_changes.rb +58 -0
- data/spec/feature_hg_history.rb +58 -0
- data/spec/featurettes/repo_creation.rb +64 -0
- data/spec/featurettes/shellout.rb +16 -0
- data/test/case_metadata.rb +10 -0
- metadata +265 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
module VCLog
|
2
|
+
|
3
|
+
# The Change class models an entry in a change log.
|
4
|
+
#
|
5
|
+
class ChangePoint
|
6
|
+
|
7
|
+
# Type of change, as assigned by hueristics.
|
8
|
+
attr_accessor :type
|
9
|
+
|
10
|
+
# The priority level of this change, as assigned by hueristics.
|
11
|
+
# This can be `nil`, as Heuristics will always make sure a
|
12
|
+
# commit has an inteer level before going out to template.
|
13
|
+
attr_accessor :level
|
14
|
+
|
15
|
+
# The descriptive label of this change, as assigned by hueristics.
|
16
|
+
attr_accessor :label
|
17
|
+
|
18
|
+
# ANSI color to apply. Actually this can be a list
|
19
|
+
# of any support ansi gem terms, but usually it's
|
20
|
+
# just the color term, such as `:red`.
|
21
|
+
attr_accessor :color
|
22
|
+
|
23
|
+
#
|
24
|
+
def initialize(change, message)
|
25
|
+
@change = change
|
26
|
+
@message = message.strip
|
27
|
+
|
28
|
+
@label = nil
|
29
|
+
@level = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
# Change from which point is derived.
|
33
|
+
attr :change
|
34
|
+
|
35
|
+
# The point's message.
|
36
|
+
attr_accessor :message
|
37
|
+
alias_method :msg, :message
|
38
|
+
alias_method :msg=, :message=
|
39
|
+
|
40
|
+
# Delegate missing methods to +change+.
|
41
|
+
def method_missing(s,*a,&b)
|
42
|
+
if @change.respond_to?(s)
|
43
|
+
@change.send(s,*a,&b)
|
44
|
+
else
|
45
|
+
p caller
|
46
|
+
super(s,*a,&b)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Change points do not have sub-points.
|
51
|
+
def points
|
52
|
+
[]
|
53
|
+
end
|
54
|
+
|
55
|
+
# Apply heuristic rules to change.
|
56
|
+
def apply_heuristics(heuristics)
|
57
|
+
heuristics.apply(self)
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
def to_h
|
62
|
+
{ 'author' => change.author,
|
63
|
+
'date' => change.date,
|
64
|
+
'id' => change.id,
|
65
|
+
'message' => message,
|
66
|
+
'type' => type
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
def to_s(*)
|
72
|
+
message
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
require 'vclog/core_ext'
|
2
|
+
require 'vclog/change'
|
3
|
+
|
4
|
+
module VCLog
|
5
|
+
|
6
|
+
# A ChangeLog encapsulates a list of Change objects.
|
7
|
+
#
|
8
|
+
class ChangeLog
|
9
|
+
|
10
|
+
include Enumerable
|
11
|
+
|
12
|
+
#DIR = File.dirname(__FILE__)
|
13
|
+
|
14
|
+
#
|
15
|
+
# Seconds in a day.
|
16
|
+
#
|
17
|
+
DAY = 24*60*60
|
18
|
+
|
19
|
+
#
|
20
|
+
# Array of Change or ChangePoint instances.
|
21
|
+
#
|
22
|
+
attr :changes
|
23
|
+
|
24
|
+
#
|
25
|
+
# Setup new ChangeLog instance.
|
26
|
+
#
|
27
|
+
# @param [Array<Change>] changes
|
28
|
+
# An array of Change objects.
|
29
|
+
#
|
30
|
+
def initialize(changes=nil)
|
31
|
+
@changes = []
|
32
|
+
@changes = changes if changes
|
33
|
+
end
|
34
|
+
|
35
|
+
#def changes=(changes)
|
36
|
+
# @changes = []
|
37
|
+
# changes.each do |change|
|
38
|
+
# case change
|
39
|
+
# when Change
|
40
|
+
# @changes << change
|
41
|
+
# else
|
42
|
+
# @changes << Change.new(change)
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#end
|
46
|
+
|
47
|
+
# Add a change entry to the log.
|
48
|
+
def change(data={})
|
49
|
+
@changes << Change.new(data)
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Sort changes in place.
|
54
|
+
#
|
55
|
+
def sort!(&block)
|
56
|
+
changes.sort!(&block)
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Iterate over each change.
|
61
|
+
#
|
62
|
+
def each(&block)
|
63
|
+
changes.each(&block)
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Is the changelog void of any changes?
|
68
|
+
#
|
69
|
+
def empty?
|
70
|
+
changes.empty?
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Return the number of changes in the changelog.
|
75
|
+
#
|
76
|
+
def size
|
77
|
+
changes.size
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# And a change to the changelog.
|
82
|
+
#
|
83
|
+
def <<(entry)
|
84
|
+
case entry
|
85
|
+
when Change, ChangePoint
|
86
|
+
@changes << entry
|
87
|
+
else
|
88
|
+
#raise "Not a Change ro ChangePoint instance - #{entry.inspect}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Return a new changelog with entries having a level higer or
|
94
|
+
# equal to the given level.
|
95
|
+
#
|
96
|
+
def above(level)
|
97
|
+
above = changes.select{ |entry| entry.level >= level }
|
98
|
+
self.class.new(above)
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# Return a new changelog with entries occuring after the
|
103
|
+
# given date limit.
|
104
|
+
#
|
105
|
+
def after(date_limit)
|
106
|
+
after = changes.select{ |entry| entry.date > date_limit + DAY }
|
107
|
+
self.class.new(after)
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Return a new changelog with entries occuring before the
|
112
|
+
# given date limit.
|
113
|
+
#
|
114
|
+
def before(date_limit)
|
115
|
+
before = changes.select{ |entry| entry.date <= date_limit + DAY }
|
116
|
+
self.class.new(before)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Return a new changelog with entries that have a specified type.
|
120
|
+
# TODO: Be able to specify which types to include or omit.
|
121
|
+
#def typed
|
122
|
+
# self.class.new(changes.select{ |e| e.type })
|
123
|
+
#end
|
124
|
+
|
125
|
+
#
|
126
|
+
def by_type
|
127
|
+
mapped = {}
|
128
|
+
changes.each do |entry|
|
129
|
+
mapped[entry.type] ||= self.class.new
|
130
|
+
mapped[entry.type] << entry
|
131
|
+
end
|
132
|
+
mapped
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
def by_author
|
137
|
+
mapped = {}
|
138
|
+
changes.each do |entry|
|
139
|
+
mapped[entry.author] ||= self.class.new
|
140
|
+
mapped[entry.author] << entry
|
141
|
+
end
|
142
|
+
mapped
|
143
|
+
end
|
144
|
+
|
145
|
+
#
|
146
|
+
def by_date
|
147
|
+
mapped = {}
|
148
|
+
changes.each do |entry|
|
149
|
+
mapped[entry.date.strftime('%Y-%m-%d')] ||= self.class.new
|
150
|
+
mapped[entry.date.strftime('%Y-%m-%d')] << entry
|
151
|
+
end
|
152
|
+
mapped = mapped.to_a.sort{ |a,b| b[0] <=> a[0] }
|
153
|
+
mapped
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
#def by_date
|
158
|
+
# mapped = {}
|
159
|
+
# changes.each do |entry|
|
160
|
+
# mapped[entry.date.strftime('%Y-%m-%d')] ||= self.class.new
|
161
|
+
# mapped[entry.date.strftime('%Y-%m-%d')] << entry
|
162
|
+
# end
|
163
|
+
# mapped
|
164
|
+
#end
|
165
|
+
|
166
|
+
#
|
167
|
+
# Convert to list of hash.
|
168
|
+
#
|
169
|
+
# @return [Array<Hash>]
|
170
|
+
#
|
171
|
+
# @todo Not a Hash! Need to rename method.
|
172
|
+
#
|
173
|
+
def to_h
|
174
|
+
map{ |change| change.to_h }
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
# TODO: THIS IS HERE AS A REMINDER ABOUT TEH XSL TEMPLATE.
|
184
|
+
# WHAT TO DO WITH IT?
|
185
|
+
|
186
|
+
=begin
|
187
|
+
###################
|
188
|
+
# Save Chaqngelog #
|
189
|
+
###################
|
190
|
+
|
191
|
+
# Save changelog as file in specified format.
|
192
|
+
def save(file, format=:gnu, *args)
|
193
|
+
case format.to_sym
|
194
|
+
when :xml
|
195
|
+
text = to_xml
|
196
|
+
#save_xsl(file)
|
197
|
+
when :html
|
198
|
+
text = to_html(*args)
|
199
|
+
when :rel
|
200
|
+
text = to_rel(file, *args)
|
201
|
+
when :yaml
|
202
|
+
text = to_yaml(file)
|
203
|
+
when :json
|
204
|
+
text = to_json(file)
|
205
|
+
else
|
206
|
+
text = to_gnu
|
207
|
+
end
|
208
|
+
|
209
|
+
FileUtils.mkdir_p(File.dirname(file))
|
210
|
+
|
211
|
+
different = true
|
212
|
+
if File.exist?(file)
|
213
|
+
different = (File.read(file) != text)
|
214
|
+
end
|
215
|
+
|
216
|
+
File.open(file, 'w') do |f|
|
217
|
+
f << text
|
218
|
+
end if different
|
219
|
+
end
|
220
|
+
|
221
|
+
#
|
222
|
+
def save_xsl(file)
|
223
|
+
#xslfile = file.chomp(File.extname(file)) + '.xsl'
|
224
|
+
xslfile = File.join(File.dirname(file), 'log.xsl')
|
225
|
+
unless File.exist?(xslfile)
|
226
|
+
FileUtils.mkdir_p(File.dirname(xslfile))
|
227
|
+
File.open(xslfile, 'w') do |f|
|
228
|
+
f << DEFAULT_LOG_XSL
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
=end
|
233
|
+
|
data/lib/vclog/cli.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'vclog'
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
module VCLog
|
5
|
+
|
6
|
+
module CLI
|
7
|
+
|
8
|
+
#
|
9
|
+
def self.register
|
10
|
+
@register ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
# Abstract base class for all command classes.
|
14
|
+
#
|
15
|
+
class Abstract
|
16
|
+
|
17
|
+
#
|
18
|
+
def self.run(argv)
|
19
|
+
new.run(argv)
|
20
|
+
rescue => err
|
21
|
+
if $DEBUG
|
22
|
+
raise err
|
23
|
+
else
|
24
|
+
puts err.message
|
25
|
+
exit -1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
def self.inherited(subclass)
|
31
|
+
CLI.register << subclass
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
def self.terms
|
36
|
+
[name.split('::').last.downcase]
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
def initialize
|
41
|
+
@options = {}
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
def options
|
46
|
+
@options
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
def parser(&block)
|
51
|
+
parser = OptionParser.new(&block)
|
52
|
+
|
53
|
+
parser.separator " "
|
54
|
+
parser.separator "SYSTEM OPTIONS:"
|
55
|
+
parser.on('--debug', 'show debugging information') do
|
56
|
+
$DEBUG = true
|
57
|
+
end
|
58
|
+
parser.on('--help' , '-h', 'display this help information') do
|
59
|
+
puts parser
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
parser
|
63
|
+
end
|
64
|
+
|
65
|
+
# Run the command.
|
66
|
+
def run(argv=nil)
|
67
|
+
argv ||= ARGV.dup
|
68
|
+
|
69
|
+
parser.parse!(argv)
|
70
|
+
|
71
|
+
@arguments = argv
|
72
|
+
|
73
|
+
root = Dir.pwd # TODO: find root
|
74
|
+
|
75
|
+
@repo = VCLog::Repo.new(root, options)
|
76
|
+
|
77
|
+
execute
|
78
|
+
end
|
79
|
+
|
80
|
+
# Repo is set in #run.
|
81
|
+
def repo
|
82
|
+
@repo
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
attr :arguments
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'vclog/cli/abstract'
|
2
|
+
|
3
|
+
module VCLog::CLI
|
4
|
+
|
5
|
+
#
|
6
|
+
class Autotag < Abstract
|
7
|
+
|
8
|
+
#
|
9
|
+
def self.terms
|
10
|
+
['autotag']
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
def parser
|
15
|
+
super do |opt|
|
16
|
+
opt.banner = "Usage: vclog autotag"
|
17
|
+
opt.separator(" ")
|
18
|
+
opt.separator("DESCRIPTION:")
|
19
|
+
opt.separator(" Ensure each entry in History has been tagged.")
|
20
|
+
opt.separator(" ")
|
21
|
+
opt.separator("SPECIAL OPTIONS:")
|
22
|
+
opt.on('--prefix', '-p', 'tag label prefix'){ options[:prefix] = true }
|
23
|
+
opt.on('--file' , '-f FILE', 'specify history file'){ options[:history_file] = file }
|
24
|
+
opt.on('--force' , '-y', 'perform tagging without confirmation'){ options[:force] = true }
|
25
|
+
opt.on('--dryrun', '-n', 'run in dryrun mode'){ $DRYRUN = true }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
def execute
|
31
|
+
repo.autotag(options[:prefix])
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|