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
data/bin/vclog-news
ADDED
data/bin/vclog-version
ADDED
data/lib/vclog.rb
ADDED
data/lib/vclog.yml
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
---
|
2
|
+
revision: 2013
|
3
|
+
type: ruby
|
4
|
+
sources:
|
5
|
+
- index
|
6
|
+
authors:
|
7
|
+
- name: Trans
|
8
|
+
email: transfire@gmail.com
|
9
|
+
organizations: []
|
10
|
+
requirements:
|
11
|
+
- version: ! '>= 2.4'
|
12
|
+
name: facets
|
13
|
+
- version: ! '>= 1.2'
|
14
|
+
name: ansi
|
15
|
+
- name: xml-simple
|
16
|
+
#- groups:
|
17
|
+
# - build
|
18
|
+
# development: true
|
19
|
+
# name: detroit
|
20
|
+
- groups:
|
21
|
+
- build
|
22
|
+
development: true
|
23
|
+
name: ergo
|
24
|
+
- groups:
|
25
|
+
- test
|
26
|
+
development: true
|
27
|
+
name: citron
|
28
|
+
- groups:
|
29
|
+
- test
|
30
|
+
development: true
|
31
|
+
name: lime
|
32
|
+
- groups:
|
33
|
+
- test
|
34
|
+
development: true
|
35
|
+
name: ae
|
36
|
+
- groups:
|
37
|
+
- test
|
38
|
+
development: true
|
39
|
+
name: rubytest-cli
|
40
|
+
conflicts: []
|
41
|
+
alternatives: []
|
42
|
+
resources:
|
43
|
+
- type: home
|
44
|
+
uri: http://rubyworks.github.com/vclog
|
45
|
+
label: Homepage
|
46
|
+
- type: code
|
47
|
+
uri: http://github.com/rubyworks/vclog
|
48
|
+
label: Source Code
|
49
|
+
repositories:
|
50
|
+
- name: upstream
|
51
|
+
scm: git
|
52
|
+
uri: git://github.com/rubyworks/vclog.git
|
53
|
+
categories: []
|
54
|
+
copyrights:
|
55
|
+
- holder: Rubyworks
|
56
|
+
year: '2009'
|
57
|
+
license: BSD-2-Clause
|
58
|
+
customs: []
|
59
|
+
paths:
|
60
|
+
lib:
|
61
|
+
- lib
|
62
|
+
created: '2006-05-09'
|
63
|
+
summary: Cross-VCS/SCM ChangeLog Generator
|
64
|
+
title: VCLog
|
65
|
+
version: 1.9.4
|
66
|
+
name: rubycut-vclog
|
67
|
+
description: VCLog is a cross-VCS/SCM ChangeLog generator.
|
68
|
+
date: '2013-03-22'
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module VCLog
|
2
|
+
|
3
|
+
module Adapters
|
4
|
+
|
5
|
+
require 'time'
|
6
|
+
require 'pathname'
|
7
|
+
require 'tempfile'
|
8
|
+
|
9
|
+
require 'vclog/changelog'
|
10
|
+
require 'vclog/change'
|
11
|
+
require 'vclog/tag'
|
12
|
+
|
13
|
+
# TODO: Could we support a "no scm" changelog based on `LOG:` entries in source files?
|
14
|
+
|
15
|
+
# TODO: Possibly use Amp or SCM gem for future version.
|
16
|
+
|
17
|
+
# Abstract base class for all version control system adapters.
|
18
|
+
#
|
19
|
+
class Abstract
|
20
|
+
|
21
|
+
#
|
22
|
+
attr :config
|
23
|
+
|
24
|
+
# Root location.
|
25
|
+
attr :root
|
26
|
+
|
27
|
+
# Heuristics object.
|
28
|
+
attr :heuristics
|
29
|
+
|
30
|
+
#
|
31
|
+
def initialize(repo)
|
32
|
+
@repo = repo
|
33
|
+
@root = repo.root
|
34
|
+
@heuristics = repo.heuristics
|
35
|
+
|
36
|
+
initialize_framework
|
37
|
+
end
|
38
|
+
|
39
|
+
# This is used if the adapter is using an external library
|
40
|
+
# to interface with the repository.
|
41
|
+
def initialize_framework
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
def extract_tags
|
46
|
+
raise "Not Implemented"
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
def extract_changes
|
51
|
+
raise "Not Implemented"
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
def tags
|
56
|
+
@tags ||= extract_tags
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
def changes
|
61
|
+
@changes ||= extract_changes
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
def change_points
|
66
|
+
@change_points ||= (
|
67
|
+
changes.inject([]){ |list, change| list.concat(change.points); list }
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
def tag?(name)
|
73
|
+
tags.find{ |t| t.name == name }
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the current verion string.
|
77
|
+
def version
|
78
|
+
if tags.last
|
79
|
+
v = tags[-1].name # TODO: ensure the latest version
|
80
|
+
v = tags[-2].name if v == 'HEAD'
|
81
|
+
else
|
82
|
+
v = '0.0.0'
|
83
|
+
end
|
84
|
+
return v
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return the latest commit as of a given date.
|
88
|
+
def change_by_date(date)
|
89
|
+
list = changes.select{ |c| c.date <= date }
|
90
|
+
list.sort_by{ |c| c.date }.last
|
91
|
+
end
|
92
|
+
|
93
|
+
# Fallback for user is `ENV['USER']`.
|
94
|
+
def user
|
95
|
+
ENV['USER']
|
96
|
+
end
|
97
|
+
|
98
|
+
# Fallback for email address is `ENV['EMAIL']`.
|
99
|
+
def email
|
100
|
+
ENV['EMAIL']
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
def repository
|
105
|
+
nil
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
def uuid
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
#
|
116
|
+
def version_tag?(tag_name)
|
117
|
+
/(v|\d)/i =~ tag_name
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
def tempfile(name, content)
|
122
|
+
mfile = Tempfile.new(name)
|
123
|
+
File.open(mfile.path, 'w'){ |f| f << content }
|
124
|
+
mfile.path
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'vclog/adapters/abstract'
|
2
|
+
|
3
|
+
module VCLog
|
4
|
+
|
5
|
+
module Adapters
|
6
|
+
|
7
|
+
# Darcs SCM adapter.
|
8
|
+
#
|
9
|
+
# FIXME: This needs to be fixed!!!!!!!
|
10
|
+
#
|
11
|
+
class Darcs < Abstract
|
12
|
+
|
13
|
+
#
|
14
|
+
def initialize(*)
|
15
|
+
raise "Darcs is not yet supported. Please help us fix that!"
|
16
|
+
end
|
17
|
+
|
18
|
+
# Is a darcs repository?
|
19
|
+
def repository?
|
20
|
+
File.directory?('_darcs')
|
21
|
+
end
|
22
|
+
|
23
|
+
# This is also a module function.
|
24
|
+
module_function :repository?
|
25
|
+
|
26
|
+
# Cached Changelog.
|
27
|
+
def changelog
|
28
|
+
@changelog ||= generate_changelog
|
29
|
+
end
|
30
|
+
|
31
|
+
# Generate Changelog object.
|
32
|
+
def generate_changelog
|
33
|
+
raise "not a darcs repository" unless repository?
|
34
|
+
|
35
|
+
log = Changelog.new
|
36
|
+
|
37
|
+
txt = `darcs changes` #--repo=#{@repository}`
|
38
|
+
|
39
|
+
txt.each_line do |line|
|
40
|
+
case line
|
41
|
+
when /^\s*$/
|
42
|
+
when /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun)/
|
43
|
+
when /^\s*tagged/
|
44
|
+
log << $'
|
45
|
+
log << "\n"
|
46
|
+
else
|
47
|
+
log << line
|
48
|
+
log << "\n"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
return log
|
53
|
+
end
|
54
|
+
|
55
|
+
# Retrieve the "revision number" from the darcs tree.
|
56
|
+
def calculate_version
|
57
|
+
raise "not a darcs repository" unless repository?
|
58
|
+
|
59
|
+
status = info.status
|
60
|
+
|
61
|
+
changes = `darcs changes`
|
62
|
+
count = 0
|
63
|
+
tag = "0.0"
|
64
|
+
|
65
|
+
changes.each("\n\n") do |change|
|
66
|
+
head, title, desc = change.split("\n", 3)
|
67
|
+
if title =~ /^ \*/
|
68
|
+
# Normal change.
|
69
|
+
count += 1
|
70
|
+
elsif title =~ /tagged (.*)/
|
71
|
+
# Tag. We look for these.
|
72
|
+
tag = $1
|
73
|
+
break
|
74
|
+
else
|
75
|
+
warn "Unparsable change: #{change}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
ver = "#{tag}.#{count.to_s}"
|
79
|
+
|
80
|
+
return ver
|
81
|
+
#format_version_stamp(ver, status) # ,released)
|
82
|
+
end
|
83
|
+
|
84
|
+
# TODO
|
85
|
+
def tag(ref, label, msg)
|
86
|
+
`darcs tag #{label}`
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'vclog/adapters/abstract'
|
2
|
+
|
3
|
+
module VCLog
|
4
|
+
|
5
|
+
module Adapters
|
6
|
+
|
7
|
+
# GIT Adapter.
|
8
|
+
#
|
9
|
+
class Git < Abstract
|
10
|
+
|
11
|
+
GIT_COMMIT_MARKER = '=====%n'
|
12
|
+
GIT_FIELD_MARKER = '-----%n'
|
13
|
+
|
14
|
+
RUBY_COMMIT_MARKER = "=====\n"
|
15
|
+
RUBY_FIELD_MARKER = "-----\n"
|
16
|
+
|
17
|
+
# Collect changes, i.e. commits.
|
18
|
+
def extract_changes
|
19
|
+
list = []
|
20
|
+
|
21
|
+
command = 'git log --name-only --pretty=format:"' +
|
22
|
+
GIT_COMMIT_MARKER +
|
23
|
+
'%ci' +
|
24
|
+
GIT_FIELD_MARKER +
|
25
|
+
'%aN' +
|
26
|
+
GIT_FIELD_MARKER +
|
27
|
+
'%H' +
|
28
|
+
GIT_FIELD_MARKER +
|
29
|
+
'%s%n%n%b' +
|
30
|
+
GIT_FIELD_MARKER +
|
31
|
+
'"'
|
32
|
+
|
33
|
+
changes = `#{command}`.split(RUBY_COMMIT_MARKER)
|
34
|
+
|
35
|
+
changes.shift # throw the first (empty) entry away
|
36
|
+
|
37
|
+
changes.each do |entry|
|
38
|
+
date, who, id, msg, files = entry.split(RUBY_FIELD_MARKER)
|
39
|
+
date = Time.parse(date)
|
40
|
+
files = files.split("\n")
|
41
|
+
list << Change.new(:id=>id, :date=>date, :who=>who, :msg=>msg, :files=>files)
|
42
|
+
end
|
43
|
+
|
44
|
+
return list
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
#def extract_files(change_list)
|
49
|
+
# change_list.each do |change|
|
50
|
+
# files = `git show --pretty="format:" --name-only #{c.id}`
|
51
|
+
# files = files.split("\n")
|
52
|
+
# change.files = files
|
53
|
+
# end
|
54
|
+
#end
|
55
|
+
|
56
|
+
# Collect tags.
|
57
|
+
#
|
58
|
+
# `git show 1.0` produces:
|
59
|
+
#
|
60
|
+
# tag 1.0
|
61
|
+
# Tagger: 7rans <transfire@gmail.com>
|
62
|
+
# Date: Sun Oct 25 09:27:58 2009 -0400
|
63
|
+
#
|
64
|
+
# version 1.0
|
65
|
+
# commit
|
66
|
+
# ...
|
67
|
+
#
|
68
|
+
# @todo This code is pretty poor, but it suffices for now.
|
69
|
+
# And we need not worry about it the future b/c eventually
|
70
|
+
# we will replace it by using the `amp` or `scm` gem.
|
71
|
+
def extract_tags
|
72
|
+
list = []
|
73
|
+
tags = `git tag -l`
|
74
|
+
tags.split(/\s+/).each do |tag|
|
75
|
+
next unless version_tag?(tag) # only version tags
|
76
|
+
id, who, date, rev, msg = nil, nil, nil, nil, nil
|
77
|
+
info = `git show #{tag}`
|
78
|
+
info, *_ = info.split(/^(commit|diff|----)/)
|
79
|
+
if /\Atag/ =~ info
|
80
|
+
msg = ''
|
81
|
+
info.lines.to_a[1..-1].each do |line|
|
82
|
+
case line
|
83
|
+
when /^Tagger:/
|
84
|
+
who = $'.strip
|
85
|
+
when /^Date:/
|
86
|
+
date = $'.strip
|
87
|
+
when /^\s*[a-f0-9]+/
|
88
|
+
id = $0.strip
|
89
|
+
else
|
90
|
+
msg << line
|
91
|
+
end
|
92
|
+
end
|
93
|
+
msg = msg.strip
|
94
|
+
|
95
|
+
#info = `git show #{tag}^ --pretty=format:"%ci|~|%H|~|"`
|
96
|
+
#cdate, id, *_ = *info.split('|~|')
|
97
|
+
|
98
|
+
info = git_show("#{tag}")
|
99
|
+
|
100
|
+
change = Change.new(info)
|
101
|
+
|
102
|
+
list << Tag.new(:id=>change.id, :name=>tag, :date=>date, :who=>who, :msg=>msg, :commit=>change)
|
103
|
+
else
|
104
|
+
#info = `git show #{tag} --pretty=format:"%cn|~|%ce|~|%ci|~|%H|~|%s|~|"`
|
105
|
+
info = git_show(tag)
|
106
|
+
change = Change.new(info)
|
107
|
+
|
108
|
+
tag_info = {
|
109
|
+
:name => tag,
|
110
|
+
:who => info[:who],
|
111
|
+
:date => info[:date],
|
112
|
+
:msg => info[:message],
|
113
|
+
:commit => change
|
114
|
+
}
|
115
|
+
list << Tag.new(tag_info)
|
116
|
+
end
|
117
|
+
|
118
|
+
#if $DEBUG
|
119
|
+
# p who, date, rev, msg
|
120
|
+
# puts
|
121
|
+
#end
|
122
|
+
|
123
|
+
#list << tag
|
124
|
+
end
|
125
|
+
|
126
|
+
return list
|
127
|
+
end
|
128
|
+
|
129
|
+
# User name of developer.
|
130
|
+
def user
|
131
|
+
@user ||= `git config user.name`.strip
|
132
|
+
end
|
133
|
+
|
134
|
+
# Email address of developer.
|
135
|
+
def email
|
136
|
+
@email ||= `git config user.email`.strip
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
def repository
|
141
|
+
@repository ||= `git config remote.origin.url`.strip
|
142
|
+
end
|
143
|
+
|
144
|
+
#
|
145
|
+
# Create a tag for the given commit reference.
|
146
|
+
#
|
147
|
+
def tag(ref, label, date, message)
|
148
|
+
file = tempfile("message", message)
|
149
|
+
date = date.strftime('%Y-%m-%d 23:59') unless String===date
|
150
|
+
|
151
|
+
cmd = %[GIT_AUTHOR_DATE='#{date}' GIT_COMMITTER_DATE='#{date}' git tag -a -F '#{file}' #{label} #{ref}]
|
152
|
+
puts cmd if $DEBUG
|
153
|
+
`#{cmd}` unless $DRYRUN
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
#
|
159
|
+
#
|
160
|
+
#
|
161
|
+
def git_show(ref)
|
162
|
+
command = 'git show ' + ref.to_s + ' --name-only --pretty=format:"' +
|
163
|
+
'%ci' +
|
164
|
+
GIT_FIELD_MARKER +
|
165
|
+
'%cn' +
|
166
|
+
GIT_FIELD_MARKER +
|
167
|
+
'%ce' +
|
168
|
+
GIT_FIELD_MARKER +
|
169
|
+
'%H' +
|
170
|
+
GIT_FIELD_MARKER +
|
171
|
+
'%s%n%n%b' +
|
172
|
+
GIT_FIELD_MARKER +
|
173
|
+
'"'
|
174
|
+
|
175
|
+
entry = `#{command}`
|
176
|
+
|
177
|
+
date, who, email, id, msg, files = entry.split(RUBY_FIELD_MARKER)
|
178
|
+
|
179
|
+
who = who + ' ' + email
|
180
|
+
date = Time.parse(date)
|
181
|
+
files = files.split("\n")
|
182
|
+
|
183
|
+
return { :date=>date, :who=>who, :id=>id, :message=>msg, :files=>files }
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|