rubycut-vclog 1.9.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|