create_changelog 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -2
- data/README.md +41 -23
- data/bin/ccl +35 -35
- data/bin/ccl~ +12 -9
- data/lib/changelog.rb +124 -0
- data/lib/changelog.rb~ +124 -0
- data/lib/changelog_filter.rb +2 -1
- data/lib/commit_changelog.rb +33 -0
- data/lib/commit_changelog.rb~ +56 -0
- data/lib/git.rb +22 -1
- data/lib/git.rb~ +72 -0
- data/lib/tag.rb +5 -6
- data/lib/tag.rb~ +51 -0
- data/lib/tag_list.rb +13 -2
- data/lib/tag_list.rb~ +62 -0
- data/lib/version.rb +1 -1
- data/lib/version.rb~ +1 -1
- metadata +28 -7
- data/lib/create_changelog.rb +0 -77
- data/lib/create_changelog.rb~ +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24eaf0e197456ddc73ee36dbe5c4befa32d7a8fb
|
4
|
+
data.tar.gz: ac2e4abb1a874e0c8d98f3bc404273c733bf48ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56de42ae4ca9ccf353baacf98df9729a9c90287871e30af061fc46d2f7087ed99a8ba1ee3f04a47707eb977c98c9f8f6c73417e419a7fb4ff28531df03b8d90b
|
7
|
+
data.tar.gz: 40ca54406f53d1f2a7106cbe393e127a7f07f0b781a5276ecec945cb3a213669c0d9807fc286805dad29b543adbf1be049abc5712e9d5cfcc4de99eae91dac96
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
Version 1.3.0 (2015-01-21)
|
2
|
+
========================================================================
|
3
|
+
|
4
|
+
- CHANGE: Omit empty lines at end of changelog.
|
5
|
+
- FIX: Do not crash if Git repository is empty.
|
6
|
+
- FIX: Do not produce any output if no changelog information found.
|
7
|
+
- FIX: Ensure unique lines if initial commit is included.
|
8
|
+
- FIX: Include the very first commit's message in the changelog.
|
9
|
+
- FIX: Omit recent changes section if there are no recent changes.
|
10
|
+
|
11
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
12
|
+
|
13
|
+
|
1
14
|
Version 1.2.0 (2015-01-18)
|
2
15
|
========================================================================
|
3
16
|
|
@@ -21,6 +34,5 @@ Version 1.0.0 (2015-01-18)
|
|
21
34
|
========================================================================
|
22
35
|
|
23
36
|
|
24
|
-
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
25
|
-
|
26
37
|
|
38
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/create_changelog.svg)](http://badge.fury.io/rb/create_changelog)
|
2
|
+
|
3
|
+
create_changelog
|
2
4
|
================
|
3
5
|
|
4
6
|
Ruby program with command-line interface that creates a changelog from
|
@@ -27,19 +29,25 @@ The reason why I chose to have special changelog lines rather than
|
|
27
29
|
commit subjects is that commits are rather technical, but I want to have
|
28
30
|
a changelog that can be read by 'normal' end users.
|
29
31
|
|
32
|
+
create_changelog assumes that each tag in the repository represents a
|
33
|
+
release version. The changelog for a version consists of the tag's name,
|
34
|
+
the tag's annotation, and the unique combined, filtered changelog lines
|
35
|
+
of the tag annotation and all commits since the previous tag.
|
36
|
+
|
30
37
|
|
31
38
|
Usage
|
32
39
|
-----
|
33
40
|
|
34
41
|
### Creating log entries
|
35
|
-
|
36
|
-
|
42
|
+
|
43
|
+
When committing, add a line to the commit message that fits the above
|
44
|
+
definition, e.g.
|
37
45
|
|
38
46
|
Implement Backup class.
|
39
47
|
|
40
48
|
- NEW: Ability to back up the files.
|
41
49
|
|
42
|
-
|
50
|
+
When releasing a new version, create an annotated tag:
|
43
51
|
|
44
52
|
Version 7.0.0-alpha.3
|
45
53
|
|
@@ -63,38 +71,41 @@ changelog entries.
|
|
63
71
|
To generate a complete change log, simply run the tool in the directory
|
64
72
|
of the git repository, or indicate a working directory:
|
65
73
|
|
66
|
-
ccl
|
74
|
+
ccl -d /home/me/my/repository
|
67
75
|
|
68
76
|
The output will be in markdown format. If you wish, you can further
|
69
77
|
process it using tools like [pandoc][] for example. Of course, it is
|
70
78
|
also possible to incorporate the command in the content files for a
|
71
79
|
static site generator such as [nanoc][].
|
72
80
|
|
73
|
-
If you want to track your log in the git repository, you
|
74
|
-
|
75
|
-
case, the tool will use "Unpublished
|
76
|
-
|
77
|
-
the tag,
|
81
|
+
If you want to track your log in the git repository, you will not yet
|
82
|
+
have an annotated tag for the version you are preparing at the time when
|
83
|
+
you generate the changelog. In this case, the tool will use "Unpublished
|
84
|
+
changes" as the heading for the latest changes. To rather use the
|
85
|
+
version number that you are about to use in the tag, execute the tool
|
86
|
+
with an optional argument:
|
78
87
|
|
79
|
-
ccl
|
88
|
+
ccl "Version 7.0.0-alpha.4"
|
89
|
+
|
90
|
+
You then use this same version number for your release tag.
|
80
91
|
|
81
92
|
Be aware that currently, the date of the most recent commit (that HEAD
|
82
93
|
points to) will be appended to the heading.
|
83
94
|
|
84
95
|
To exclude recent changes that were logged since the last tag:
|
85
96
|
|
86
|
-
ccl
|
87
|
-
ccl
|
97
|
+
ccl --no-recent
|
98
|
+
ccl -n
|
88
99
|
|
89
100
|
To just see the (undecorated) changelog entries since the last tag, use:
|
90
101
|
|
91
|
-
ccl
|
92
|
-
ccl
|
102
|
+
ccl --recent
|
103
|
+
ccl -r
|
93
104
|
|
94
105
|
This can be handy if you want to add a log of recent changes to your tag
|
95
106
|
annotation. For example, using the Vim text editor, issue:
|
96
107
|
|
97
|
-
:r!ccl
|
108
|
+
:r!ccl -r
|
98
109
|
|
99
110
|
The tool will make sure that no changelog lines are duplicated.
|
100
111
|
|
@@ -103,8 +114,17 @@ Changelog format
|
|
103
114
|
----------------
|
104
115
|
|
105
116
|
The changelog format resembles the [suggestions][kacl] made by Olivier
|
106
|
-
Lacan
|
107
|
-
|
117
|
+
Lacan, but it does not fully comply with Olivier's specification. I have
|
118
|
+
not yet have the time to implement automatic generation of subheadings.
|
119
|
+
Maybe I'll add the feature in the future.
|
120
|
+
|
121
|
+
|
122
|
+
To do
|
123
|
+
-----
|
124
|
+
|
125
|
+
- Add automatic subheadings
|
126
|
+
- Add ability to handle multi-line change log entries
|
127
|
+
- Add to-do list feature
|
108
128
|
|
109
129
|
|
110
130
|
Live example
|
@@ -118,11 +138,8 @@ Live example
|
|
118
138
|
Code
|
119
139
|
----
|
120
140
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
Alternatively, you may browse
|
125
|
-
<http://www.rubydoc.info/github/bovender/create-changelog>.
|
141
|
+
The code is documented in [Yard][] style. The `doc` subdirectory is
|
142
|
+
git-ignored so you can safely generate the docs.
|
126
143
|
|
127
144
|
|
128
145
|
License
|
@@ -148,5 +165,6 @@ License
|
|
148
165
|
[nanoc]: http://nanoc.ws
|
149
166
|
[kacl]: http://keepachangelog.com
|
150
167
|
[CHANGELOG.md]: CHANGELOG.md
|
168
|
+
[Yard]: http://www.rubydoc.info/gems/yard
|
151
169
|
|
152
170
|
<!-- vim: set tw=72 : -->
|
data/bin/ccl
CHANGED
@@ -19,54 +19,54 @@
|
|
19
19
|
# The filtered lines are sorted and written to standard out.
|
20
20
|
|
21
21
|
require 'optparse'
|
22
|
-
require_relative '../lib/
|
22
|
+
require_relative '../lib/changelog.rb'
|
23
23
|
require_relative '../lib/git.rb'
|
24
24
|
require_relative '../lib/version.rb'
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
options[:only_recent] = true
|
37
|
-
end
|
38
|
-
opts.on("-n", "--no-recent",
|
39
|
-
"Exclude the most recent changes (from untagged commits)") do
|
40
|
-
options[:no_recent] = true
|
41
|
-
end
|
42
|
-
opts.on("-d WORKING_DIR", "--dir WORKING_DIR",
|
43
|
-
"Use alternate working directory") do |dir|
|
44
|
-
working_dir = dir
|
45
|
-
end
|
46
|
-
opts.on("-v", "--version", "Print version information and exit.") do
|
47
|
-
puts CreateChangelog::VERSION
|
48
|
-
exit
|
49
|
-
end
|
26
|
+
options = {}
|
27
|
+
working_dir = Dir.pwd
|
28
|
+
option_parser = OptionParser.new do |opts|
|
29
|
+
exe_name = File.basename($PROGRAM_NAME)
|
30
|
+
opts.banner = "create_changelog version #{CreateChangelog::VERSION}\n"
|
31
|
+
opts.banner += "Creates changelog from log entries in git log\n"
|
32
|
+
opts.banner += "Usage: #{exe_name} [options] [current_version]"
|
33
|
+
opts.on("-r", "--recent",
|
34
|
+
"Include only most recent changes") do
|
35
|
+
options[:only_recent] = true
|
50
36
|
end
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
37
|
+
opts.on("-n", "--no-recent",
|
38
|
+
"Exclude the most recent changes (from untagged commits)") do
|
39
|
+
options[:no_recent] = true
|
40
|
+
end
|
41
|
+
opts.on("-d WORKING_DIR", "--dir WORKING_DIR",
|
42
|
+
"Use alternate working directory") do |dir|
|
43
|
+
working_dir = dir
|
55
44
|
end
|
45
|
+
opts.on("-v", "--version", "Print version information and exit.") do
|
46
|
+
puts CreateChangelog::VERSION
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
end
|
50
|
+
option_parser.parse!
|
56
51
|
|
57
|
-
|
58
|
-
abort "FATAL:
|
52
|
+
if options[:no_recent] and options[:only_recent]
|
53
|
+
abort "FATAL: Cannot combine --recent and --no-recent"
|
54
|
+
end
|
59
55
|
|
56
|
+
Dir.chdir(working_dir) do
|
57
|
+
abort "FATAL: Not a git repository." unless Git.is_git_repository?
|
58
|
+
|
59
|
+
unless Git.is_empty_repository?
|
60
60
|
change_log = Changelog.new
|
61
61
|
change_log.recent_changes_heading = ARGV[0] unless ARGV.empty?
|
62
62
|
if options[:only_recent]
|
63
|
-
|
63
|
+
output = change_log.generate_recent
|
64
|
+
puts output if output
|
64
65
|
else
|
65
|
-
|
66
|
+
output = change_log.generate(options[:no_recent])
|
67
|
+
puts output.rstrip if output
|
66
68
|
end
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
70
|
-
main
|
71
|
-
|
72
72
|
# vim: nospell
|
data/bin/ccl~
CHANGED
@@ -19,7 +19,7 @@
|
|
19
19
|
# The filtered lines are sorted and written to standard out.
|
20
20
|
|
21
21
|
require 'optparse'
|
22
|
-
require_relative '../lib/
|
22
|
+
require_relative '../lib/changelog.rb'
|
23
23
|
require_relative '../lib/git.rb'
|
24
24
|
require_relative '../lib/version.rb'
|
25
25
|
|
@@ -33,7 +33,6 @@ def main
|
|
33
33
|
opts.banner += "Usage: #{exe_name} [options] [current_version]"
|
34
34
|
opts.on("-r", "--recent",
|
35
35
|
"Include only most recent changes") do
|
36
|
-
abort "FATAL: Cannot combine --recent and --no-recent" if options[:no_recent]
|
37
36
|
options[:only_recent] = true
|
38
37
|
end
|
39
38
|
opts.on("-n", "--no-recent",
|
@@ -52,18 +51,22 @@ def main
|
|
52
51
|
option_parser.parse!
|
53
52
|
|
54
53
|
if options[:no_recent] and options[:only_recent]
|
55
|
-
abort "FATAL: Cannot combine --recent and --no-recent"
|
54
|
+
abort "FATAL: Cannot combine --recent and --no-recent"
|
56
55
|
end
|
57
56
|
|
58
57
|
Dir.chdir(working_dir) do
|
59
58
|
abort "FATAL: Not a git repository." unless Git.is_git_repository?
|
60
59
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
60
|
+
unless Git.is_empty_repository?
|
61
|
+
change_log = Changelog.new
|
62
|
+
change_log.recent_changes_heading = ARGV[0] unless ARGV.empty?
|
63
|
+
if options[:only_recent]
|
64
|
+
output = change_log.generate_recent
|
65
|
+
puts output if output
|
66
|
+
else
|
67
|
+
output = change_log.generate(options[:no_recent])
|
68
|
+
puts output.rstrip if output
|
69
|
+
end
|
67
70
|
end
|
68
71
|
end
|
69
72
|
end
|
data/lib/changelog.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# changelog.rb, part of Create-changelog
|
2
|
+
# Copyright 2015 Daniel Kraus
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require_relative './commit_changelog.rb'
|
15
|
+
require_relative './tag_list.rb'
|
16
|
+
require_relative './tag.rb'
|
17
|
+
|
18
|
+
# Central class that puts together the changelog.
|
19
|
+
class Changelog
|
20
|
+
|
21
|
+
# Heading for the most recent changes.
|
22
|
+
attr_writer :recent_changes_heading
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@recent_changes_heading = "Unpublished changes"
|
26
|
+
end
|
27
|
+
|
28
|
+
@@tags = nil
|
29
|
+
|
30
|
+
# Generates a decorated changelog for the entire commit history.
|
31
|
+
#
|
32
|
+
# @param [bool] exclude_recent
|
33
|
+
# Indicates whether to exclude recent changelog lines that were
|
34
|
+
# added since the last tag.
|
35
|
+
#
|
36
|
+
# @return [String]
|
37
|
+
# Decorated changelog, or nil if no lines were found.
|
38
|
+
#
|
39
|
+
def generate(exclude_recent = false)
|
40
|
+
# Traverse tags
|
41
|
+
@@tags = TagList.new(!exclude_recent)
|
42
|
+
output = String.new
|
43
|
+
@@tags.list.each_cons(2) do |current_tag, previous_tag|
|
44
|
+
output << generate_for(current_tag, previous_tag)
|
45
|
+
end
|
46
|
+
output.length > 0 ? output : nil
|
47
|
+
end
|
48
|
+
|
49
|
+
# Generates a simple, undecorated list of changelog entries
|
50
|
+
# since the most recent tag.
|
51
|
+
#
|
52
|
+
# @return [Array]
|
53
|
+
# Array of changelog lines, or nil if no lines were found.
|
54
|
+
#
|
55
|
+
def generate_recent
|
56
|
+
@@tags = TagList.new
|
57
|
+
log = CommitChangelog.new(@@tags.list[0], @@tags.list[1])
|
58
|
+
# Explicitly add initial commit if there is no tag yet
|
59
|
+
# This is necessary because HEAD..OTHER_COMMIT does not include
|
60
|
+
# OTHER_COMMIT's message, which is the desired behavior if
|
61
|
+
# OTHER_COMMIT is a tag for a previous version, but undesired
|
62
|
+
# if OTHER_COMMIT is the initial commit of the repository.
|
63
|
+
log.add_commit @@tags.list[1] if @@tags.list.length == 2
|
64
|
+
log.changelog
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# Generates decorated changelog information including the current_tag's
|
70
|
+
# annotation and all changelog lines written in commit messages since the
|
71
|
+
# previous_tag. Note that this will exclude previous_tag's annotation,
|
72
|
+
# except if previous_tag is not a tag, but the initial commit in the
|
73
|
+
# repository.
|
74
|
+
#
|
75
|
+
# @param [String] current_tag
|
76
|
+
# Version tag for which to collect changelog information.
|
77
|
+
#
|
78
|
+
# @param [String] previous_tag
|
79
|
+
# Previous version tag whose changelog information does not belong to
|
80
|
+
# the current version's changelog information. However, if previous_tag
|
81
|
+
# is the Sha-1 hash of the initial commit, its changelog lines _will_ be
|
82
|
+
# included.
|
83
|
+
#
|
84
|
+
# @return [String]
|
85
|
+
# Changelog decorated with markdown formatting, or empty string.
|
86
|
+
#
|
87
|
+
def generate_for(current_tag, previous_tag)
|
88
|
+
tag = Tag.new(current_tag)
|
89
|
+
commit_changelog = CommitChangelog.new(current_tag, previous_tag)
|
90
|
+
|
91
|
+
# If previous_tag is the initial commit, make sure to include its message
|
92
|
+
commit_changelog.add_commit previous_tag if previous_tag == @@tags.list[-1]
|
93
|
+
|
94
|
+
# Combine changelog entries from tag annotation and commit messages
|
95
|
+
if tag.changelog
|
96
|
+
combined_changelog = tag.changelog.concat(commit_changelog.changelog)
|
97
|
+
else
|
98
|
+
combined_changelog = commit_changelog.changelog
|
99
|
+
end
|
100
|
+
combined_changelog.uniq! if combined_changelog
|
101
|
+
|
102
|
+
output = String.new
|
103
|
+
tag.heading = @recent_changes_heading unless tag.heading
|
104
|
+
if tag.heading and (tag.text or combined_changelog)
|
105
|
+
output << tag.heading + " (#{tag.date})\n"
|
106
|
+
output << "=" * 72 + "\n"
|
107
|
+
end
|
108
|
+
output << tag.text.join("\n") if tag.text
|
109
|
+
output << "\n" if tag.heading or tag.text
|
110
|
+
output << combined_changelog.join("\n") + "\n" if combined_changelog
|
111
|
+
output << end_separator if tag.text or combined_changelog
|
112
|
+
output
|
113
|
+
end
|
114
|
+
|
115
|
+
# Markdown-compatible horizontal 'ruler'.
|
116
|
+
#
|
117
|
+
# @return [String]
|
118
|
+
#
|
119
|
+
def end_separator
|
120
|
+
"\n" + ("* " * 36) +"\n\n\n"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# vim: nospell
|
data/lib/changelog.rb~
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# changelog.rb, part of Create-changelog
|
2
|
+
# Copyright 2015 Daniel Kraus
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require_relative './commit_changelog.rb'
|
15
|
+
require_relative './tag_list.rb'
|
16
|
+
require_relative './tag.rb'
|
17
|
+
|
18
|
+
# Central class that puts together the changelog.
|
19
|
+
class Changelog
|
20
|
+
|
21
|
+
# Heading for the most recent changes.
|
22
|
+
attr_writer :recent_changes_heading
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@recent_changes_heading = "Unpublished changes"
|
26
|
+
end
|
27
|
+
|
28
|
+
@@tags = nil
|
29
|
+
|
30
|
+
# Generates a decorated changelog for the entire commit history.
|
31
|
+
#
|
32
|
+
# @param [bool] exclude_recent
|
33
|
+
# Indicates whether to exclude recent changelog lines that were
|
34
|
+
# added since the last tag.
|
35
|
+
#
|
36
|
+
# @return [String]
|
37
|
+
# Decorated changelog, or nil if no lines were found.
|
38
|
+
#
|
39
|
+
def generate(exclude_recent = false)
|
40
|
+
# Traverse tags
|
41
|
+
@@tags = TagList.new(!exclude_recent)
|
42
|
+
output = String.new
|
43
|
+
@@tags.list.each_cons(2) do |current_tag, previous_tag|
|
44
|
+
output << generate_for(current_tag, previous_tag)
|
45
|
+
end
|
46
|
+
output.length > 0 ? output : nil
|
47
|
+
end
|
48
|
+
|
49
|
+
# Generates a simple, undecorated list of changelog entries
|
50
|
+
# since the most recent tag.
|
51
|
+
#
|
52
|
+
# @return [Array]
|
53
|
+
# Array of changelog lines, or nil if no lines were found.
|
54
|
+
#
|
55
|
+
def generate_recent
|
56
|
+
@@tags = TagList.new
|
57
|
+
log = CommitChangelog.new(@@tags.list[0], @@tags.list[1])
|
58
|
+
# Explicitly add initial commit if there is no tag yet
|
59
|
+
# This is necessary because HEAD..OTHER_COMMIT does not include
|
60
|
+
# OTHER_COMMIT's message, which is the desired behavior if
|
61
|
+
# OTHER_COMMIT is a tag for a previous version, but undesired
|
62
|
+
# if OTHER_COMMIT is the initial commit of the repository.
|
63
|
+
log.add_commit @@tags.list[1] if @@tags.list.length == 2
|
64
|
+
log.changelog
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# Generates decorated changelog information including the current_tag's
|
70
|
+
# annotation and all changelog lines written in commit messages since the
|
71
|
+
# previous_tag. Note that this will exclude previous_tag's annotation,
|
72
|
+
# except if previous_tag is not a tag, but the initial commit in the
|
73
|
+
# repository.
|
74
|
+
#
|
75
|
+
# @param [String] current_tag
|
76
|
+
# Version tag for which to collect changelog information.
|
77
|
+
#
|
78
|
+
# @param [String] previous_tag
|
79
|
+
# Previous version tag whose changelog information does not belong to
|
80
|
+
# the current version's changelog information. However, if previous_tag
|
81
|
+
# is the Sha-1 hash of the initial commit, its changelog lines _will_ be
|
82
|
+
# included.
|
83
|
+
#
|
84
|
+
# @return [String]
|
85
|
+
# Changelog decorated with markdown formatting, or empty string.
|
86
|
+
#
|
87
|
+
def generate_for(current_tag, previous_tag)
|
88
|
+
tag = Tag.new(current_tag)
|
89
|
+
commit_changelog = CommitChangelog.new(current_tag, previous_tag)
|
90
|
+
|
91
|
+
# If previous_tag is the initial commit, make sure to include its message
|
92
|
+
commit_changelog.add_commit previous_tag if previous_tag == @@tags.list[-1]
|
93
|
+
|
94
|
+
# Combine changelog entries from tag annotation and commit messages
|
95
|
+
if tag.changelog
|
96
|
+
combined_changelog = tag.changelog.concat(commit_changelog.changelog)
|
97
|
+
else
|
98
|
+
combined_changelog = commit_changelog.changelog
|
99
|
+
end
|
100
|
+
combined_changelog.uniq! if combined_changelog
|
101
|
+
|
102
|
+
output = String.new
|
103
|
+
tag.heading = @recent_changes_heading unless tag.heading
|
104
|
+
if tag.heading and (tag.text or combined_changelog)
|
105
|
+
output << tag.heading + " (#{tag.date})\n"
|
106
|
+
output << "=" * 72 + "\n"
|
107
|
+
end
|
108
|
+
output << tag.text.join("\n") if tag.text
|
109
|
+
output << "\n" if tag.heading or tag.text
|
110
|
+
output << combined_changelog.join("\n") + "\n" if combined_changelog
|
111
|
+
output << end_separator if tag.text or combined_changelog
|
112
|
+
output
|
113
|
+
end
|
114
|
+
|
115
|
+
# Markdown-compatible horizontal 'ruler'.
|
116
|
+
#
|
117
|
+
# @return [String]
|
118
|
+
#
|
119
|
+
def end_separator
|
120
|
+
"\n" + ("* " * 36) +"\n\n\n"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# vim: nospell
|
data/lib/changelog_filter.rb
CHANGED
@@ -30,10 +30,11 @@ class ChangelogFilter
|
|
30
30
|
fail "Must call this factory with Array, not " + ary.class.to_s
|
31
31
|
end
|
32
32
|
filter = ChangelogFilter.new
|
33
|
-
log,
|
33
|
+
log, text = ary.partition do |line|
|
34
34
|
line.match(pattern)
|
35
35
|
end
|
36
36
|
filter.changelog = log.uniq.sort.remove_indent if log.length > 0
|
37
|
+
filter.other_text = text if text.length > 0
|
37
38
|
filter
|
38
39
|
end
|
39
40
|
|
data/lib/commit_changelog.rb
CHANGED
@@ -15,17 +15,50 @@ require_relative 'changelog_filter'
|
|
15
15
|
|
16
16
|
# Filters commit messages for changelog entries.
|
17
17
|
class CommitChangelog
|
18
|
+
|
18
19
|
# Contains changelog entries of the commits.
|
19
20
|
attr_reader :changelog
|
20
21
|
|
21
22
|
# Instantiates an object containing changelog entries between
|
22
23
|
# two git commits.
|
24
|
+
#
|
25
|
+
# @param [String] to_commit
|
26
|
+
# Most recent commit whose changelog lines to include.
|
27
|
+
#
|
28
|
+
# @param [String] from_commit
|
29
|
+
# Earlier commit whose changelog lines will _not_ be included.
|
30
|
+
#
|
31
|
+
# @return [Array]
|
32
|
+
# Array of changelog lines, or nil if none were found.
|
33
|
+
#
|
23
34
|
def initialize(to_commit, from_commit)
|
24
35
|
pattern = ChangelogFilter.pattern
|
25
36
|
messages = Git.get_filtered_messages(from_commit, to_commit, pattern)
|
26
37
|
filter = ChangelogFilter.FromString(messages)
|
27
38
|
@changelog = filter.changelog
|
28
39
|
end
|
40
|
+
|
41
|
+
# Adds changelog information contained in a specific commit message. This
|
42
|
+
# method is typically used to parse the initial commit's commit message.
|
43
|
+
#
|
44
|
+
# @param [String] commit
|
45
|
+
# Sha-1 of the commit whose commit message to filter for changelog lines.
|
46
|
+
#
|
47
|
+
# @return
|
48
|
+
# Undefined
|
49
|
+
#
|
50
|
+
def add_commit(commit)
|
51
|
+
pattern = ChangelogFilter.pattern
|
52
|
+
filtered_text = Git.get_filtered_message(commit, pattern)
|
53
|
+
if filtered_text
|
54
|
+
filtered_lines = filtered_text.split("\n").uniq
|
55
|
+
if @changelog
|
56
|
+
@changelog = @changelog.concat(filtered_lines).uniq
|
57
|
+
else
|
58
|
+
@changelog = filtered_lines
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
29
62
|
end
|
30
63
|
|
31
64
|
# vim: nospell
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# commit_changelog.rb, part of Create-changelog
|
2
|
+
# Copyright 2015 Daniel Kraus
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require_relative 'changelog_filter'
|
15
|
+
|
16
|
+
# Filters commit messages for changelog entries.
|
17
|
+
class CommitChangelog
|
18
|
+
|
19
|
+
# Contains changelog entries of the commits.
|
20
|
+
attr_reader :changelog
|
21
|
+
|
22
|
+
# Instantiates an object containing changelog entries between
|
23
|
+
# two git commits.
|
24
|
+
#
|
25
|
+
# @param [String] to_commit
|
26
|
+
# Most recent commit whose changelog lines to include.
|
27
|
+
#
|
28
|
+
# @param [String] from_commit
|
29
|
+
# Earlier commit whose changelog lines will _not_ be included.
|
30
|
+
#
|
31
|
+
# @return [Array]
|
32
|
+
# Array of changelog lines, or nil if none were found.
|
33
|
+
#
|
34
|
+
def initialize(to_commit, from_commit)
|
35
|
+
pattern = ChangelogFilter.pattern
|
36
|
+
messages = Git.get_filtered_messages(from_commit, to_commit, pattern)
|
37
|
+
filter = ChangelogFilter.FromString(messages)
|
38
|
+
@changelog = filter.changelog
|
39
|
+
end
|
40
|
+
|
41
|
+
# Adds changelog information contained in a specific commit message.
|
42
|
+
def add_commit(commit)
|
43
|
+
pattern = ChangelogFilter.pattern
|
44
|
+
filtered_text = Git.get_filtered_message(commit, pattern)
|
45
|
+
if filtered_text
|
46
|
+
filtered_lines = filtered_text.split("\n").uniq
|
47
|
+
if @changelog
|
48
|
+
@changelog = @changelog.concat(filtered_lines).uniq
|
49
|
+
else
|
50
|
+
@changelog = filtered_lines
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# vim: nospell
|
data/lib/git.rb
CHANGED
@@ -17,19 +17,34 @@ require_relative 'tag_list'
|
|
17
17
|
class Git
|
18
18
|
|
19
19
|
# Determines whether the (current) directory is a git repository
|
20
|
+
#
|
21
|
+
# @param [String] dir
|
22
|
+
# Directory to check; if nil, uses the current directory.
|
23
|
+
#
|
24
|
+
# @return [bool]
|
25
|
+
# True if the directory is a Git repository, false if not.
|
20
26
|
def self.is_git_repository?(dir = nil)
|
21
27
|
dir = Dir.pwd if dir.nil?
|
22
28
|
system("git status > /dev/null 2>&1")
|
23
29
|
$? == 0
|
24
30
|
end
|
25
31
|
|
32
|
+
# Determines if the repository in the current directory is empty.
|
33
|
+
#
|
34
|
+
def self.is_empty_repository?
|
35
|
+
`git show HEAD > /dev/null 2>&1`
|
36
|
+
$? != 0
|
37
|
+
end
|
38
|
+
|
26
39
|
# Retrieves the first 99 lines of the annotation of a tag.
|
40
|
+
#
|
27
41
|
def self.get_tag_annotation(tag)
|
28
42
|
test_tag tag
|
29
43
|
`git tag -l -n99 #{tag}`.rstrip
|
30
44
|
end
|
31
45
|
|
32
|
-
# Retrieves the date of a tag
|
46
|
+
# Retrieves the author date of a tag
|
47
|
+
#
|
33
48
|
def self.get_tag_date(tag)
|
34
49
|
test_tag tag
|
35
50
|
`git log -1 --format=format:%ai #{tag}`
|
@@ -41,6 +56,12 @@ class Git
|
|
41
56
|
`git log #{from_commit}..#{to_commit} -E --grep='#{filter}' --format=%b`
|
42
57
|
end
|
43
58
|
|
59
|
+
# Retrieves one commit message and filters it
|
60
|
+
# Todo: Armor this against code injection!
|
61
|
+
def self.get_filtered_message(commit, filter)
|
62
|
+
`git log #{commit} -E --grep='#{filter}' --format=%b`
|
63
|
+
end
|
64
|
+
|
44
65
|
@@tags = nil
|
45
66
|
|
46
67
|
# Ensures lazy loading of the tag list to enable calling code
|
data/lib/git.rb~
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# git.rb, part of Create-changelog
|
2
|
+
# Copyright 2015 Daniel Kraus
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require_relative 'tag_list'
|
15
|
+
|
16
|
+
# A static wrapper class for git
|
17
|
+
class Git
|
18
|
+
|
19
|
+
# Determines whether the (current) directory is a git repository
|
20
|
+
def self.is_git_repository?(dir = nil)
|
21
|
+
dir = Dir.pwd if dir.nil?
|
22
|
+
system("git status > /dev/null 2>&1")
|
23
|
+
$? == 0
|
24
|
+
end
|
25
|
+
|
26
|
+
# Determines if the repository in the current directory is empty.
|
27
|
+
def self.is_empty_repository?
|
28
|
+
`git show HEAD > /dev/null 2>&1`
|
29
|
+
$? != 0
|
30
|
+
end
|
31
|
+
|
32
|
+
# Retrieves the first 99 lines of the annotation of a tag.
|
33
|
+
def self.get_tag_annotation(tag)
|
34
|
+
test_tag tag
|
35
|
+
`git tag -l -n99 #{tag}`.rstrip
|
36
|
+
end
|
37
|
+
|
38
|
+
# Retrieves the date of a tag
|
39
|
+
def self.get_tag_date(tag)
|
40
|
+
test_tag tag
|
41
|
+
`git log -1 --format=format:%ai #{tag}`
|
42
|
+
end
|
43
|
+
|
44
|
+
# Retrieves commit messages and filters them
|
45
|
+
# Todo: Armor this against code injection!
|
46
|
+
def self.get_filtered_messages(from_commit, to_commit, filter)
|
47
|
+
`git log #{from_commit}..#{to_commit} -E --grep='#{filter}' --format=%b`
|
48
|
+
end
|
49
|
+
|
50
|
+
# Retrieves one commit message and filters it
|
51
|
+
# Todo: Armor this against code injection!
|
52
|
+
def self.get_filtered_message(commit, filter)
|
53
|
+
`git log #{commit} -E --grep='#{filter}' --format=%b`
|
54
|
+
end
|
55
|
+
|
56
|
+
@@tags = nil
|
57
|
+
|
58
|
+
# Ensures lazy loading of the tag list to enable calling code
|
59
|
+
# to change the working directory first.
|
60
|
+
def self.tags
|
61
|
+
@@tags = TagList.new unless @@tags
|
62
|
+
@@tags
|
63
|
+
end
|
64
|
+
|
65
|
+
# Tests if the given tag exists and fails if it doesn't
|
66
|
+
def self.test_tag(tag)
|
67
|
+
fail "Invalid tag: #{tag}" unless tags.list.include?(tag)
|
68
|
+
end
|
69
|
+
private_class_method :test_tag, :tags
|
70
|
+
end
|
71
|
+
|
72
|
+
# vim: nospell
|
data/lib/tag.rb
CHANGED
@@ -15,7 +15,7 @@ require 'date'
|
|
15
15
|
require_relative 'git'
|
16
16
|
require_relative 'changelog_filter'
|
17
17
|
|
18
|
-
# Represents a
|
18
|
+
# Represents a Git tag and its annotation.
|
19
19
|
class Tag
|
20
20
|
# The heading of the tag annotation.
|
21
21
|
attr_accessor :heading
|
@@ -30,10 +30,9 @@ class Tag
|
|
30
30
|
attr_reader :date
|
31
31
|
|
32
32
|
# Gets change information for a specific tagged version.
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# from the commit messages, and only unique entries are used.
|
33
|
+
#
|
34
|
+
# @param [String] tag
|
35
|
+
# Tag for which to instantiate the class.
|
37
36
|
def initialize(tag)
|
38
37
|
annotation = Git.get_tag_annotation(tag)
|
39
38
|
@date = Date.parse(Git.get_tag_date(tag))
|
@@ -42,7 +41,7 @@ class Tag
|
|
42
41
|
@heading = annotation.shift
|
43
42
|
@heading = @heading.split(' ')[1..-1].join(' ') if @heading
|
44
43
|
filter = ChangelogFilter.FromArray(annotation)
|
45
|
-
@text = filter.other_text.remove_indent
|
44
|
+
@text = filter.other_text.remove_indent if filter.other_text
|
46
45
|
@changelog = filter.changelog
|
47
46
|
end
|
48
47
|
end
|
data/lib/tag.rb~
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# tag.rb, part of Create-changelog
|
2
|
+
# Copyright 2015 Daniel Kraus
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require 'date'
|
15
|
+
require_relative 'git'
|
16
|
+
require_relative 'changelog_filter'
|
17
|
+
|
18
|
+
# Represents a git tag and its annotation.
|
19
|
+
class Tag
|
20
|
+
# The heading of the tag annotation.
|
21
|
+
attr_accessor :heading
|
22
|
+
|
23
|
+
# Array of lines in the tag annotation that are not changelog entries.
|
24
|
+
attr_reader :text
|
25
|
+
|
26
|
+
# Array of lines in the tag annotation that are changelog entries.
|
27
|
+
attr_reader :changelog
|
28
|
+
|
29
|
+
# Author commit date of the tag
|
30
|
+
attr_reader :date
|
31
|
+
|
32
|
+
# Gets change information for a specific tagged version.
|
33
|
+
# This will prepend the summary for the annotated tag before
|
34
|
+
# the list of changes. If the tag annotation contains changelog
|
35
|
+
# entries, they are merged with the changelog entries filtered
|
36
|
+
# from the commit messages, and only unique entries are used.
|
37
|
+
def initialize(tag)
|
38
|
+
annotation = Git.get_tag_annotation(tag)
|
39
|
+
@date = Date.parse(Git.get_tag_date(tag))
|
40
|
+
if annotation
|
41
|
+
annotation = annotation.split("\n")
|
42
|
+
@heading = annotation.shift
|
43
|
+
@heading = @heading.split(' ')[1..-1].join(' ') if @heading
|
44
|
+
filter = ChangelogFilter.FromArray(annotation)
|
45
|
+
@text = filter.other_text.remove_indent if filter.other_text
|
46
|
+
@changelog = filter.changelog
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# vim: nospell
|
data/lib/tag_list.rb
CHANGED
@@ -24,8 +24,10 @@ class TagList
|
|
24
24
|
attr_reader :list
|
25
25
|
|
26
26
|
# Instantiates the tag list.
|
27
|
-
#
|
28
|
-
#
|
27
|
+
#
|
28
|
+
# @param [bool] include_head
|
29
|
+
# Indicates whether or not to include the most recent changes.
|
30
|
+
#
|
29
31
|
def initialize(include_head = true)
|
30
32
|
@include_head = include_head
|
31
33
|
@list = build_list
|
@@ -33,6 +35,9 @@ class TagList
|
|
33
35
|
|
34
36
|
# Returns the most recent tag in the git repository,
|
35
37
|
# or the sha1 of the initial commit if there is no tag.
|
38
|
+
#
|
39
|
+
# @return [String]
|
40
|
+
#
|
36
41
|
def latest_tag
|
37
42
|
# Index 0 is HEAD
|
38
43
|
# Index 1 is most recent tag or first commit
|
@@ -46,10 +51,16 @@ class TagList
|
|
46
51
|
# of the repository. Usually there should be not more than
|
47
52
|
# one such commit.
|
48
53
|
# See http://stackoverflow.com/a/1007545/270712
|
54
|
+
#
|
49
55
|
def get_initial_commit
|
50
56
|
`git rev-list --max-parents=0 HEAD`.chomp
|
51
57
|
end
|
52
58
|
|
59
|
+
# Builds a list of Git tags and encloses it with HEAD and the
|
60
|
+
# Sha-1 of the initial commit.
|
61
|
+
#
|
62
|
+
# @return [Array]
|
63
|
+
# Array of tags, surrounded by HEAD and the Sha-1 of the initial commit.
|
53
64
|
def build_list
|
54
65
|
tags = []
|
55
66
|
tags << get_initial_commit
|
data/lib/tag_list.rb~
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# TagList, part of Create-changelog
|
2
|
+
# Copyright 2015 Daniel Kraus
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
# Builds a list of tags in the current git repository.
|
16
|
+
# The tags are enclosed by the sha1 of the first commit
|
17
|
+
# and optionally "HEAD" to allow traversing the list
|
18
|
+
# with each_con to obtain start and end points of
|
19
|
+
# developmental epochs.
|
20
|
+
class TagList
|
21
|
+
# Returns an array of tag names surrounded by HEAD
|
22
|
+
# at the top and the sha1 of the first commit at the
|
23
|
+
# bottom.
|
24
|
+
attr_reader :list
|
25
|
+
|
26
|
+
# Instantiates the tag list.
|
27
|
+
# include_head indicates whether or not to include
|
28
|
+
# the most recent changes
|
29
|
+
def initialize(include_head = true)
|
30
|
+
@include_head = include_head
|
31
|
+
@list = build_list
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the most recent tag in the git repository,
|
35
|
+
# or the sha1 of the initial commit if there is no tag.
|
36
|
+
def latest_tag
|
37
|
+
# Index 0 is HEAD
|
38
|
+
# Index 1 is most recent tag or first commit
|
39
|
+
@list[1]
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# Returns the sha1 of the initial commit.
|
45
|
+
# In fact, this function returns all parentless commits
|
46
|
+
# of the repository. Usually there should be not more than
|
47
|
+
# one such commit.
|
48
|
+
# See http://stackoverflow.com/a/1007545/270712
|
49
|
+
def get_initial_commit
|
50
|
+
`git rev-list --max-parents=0 HEAD`.chomp
|
51
|
+
end
|
52
|
+
|
53
|
+
def build_list
|
54
|
+
tags = []
|
55
|
+
tags << get_initial_commit
|
56
|
+
tags += `git tag`.split("\n").map { |s| s.rstrip }
|
57
|
+
tags << "HEAD" if @include_head
|
58
|
+
tags.reverse
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# vim: nospell
|
data/lib/version.rb
CHANGED
data/lib/version.rb~
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: create_changelog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Kraus
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
12
|
-
dependencies:
|
11
|
+
date: 2015-01-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aruba
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: "\t\tRuby program with command-line interface that creates a changelog
|
14
28
|
from log\n\t\tlines in a git repository that can be read and understood by end users.\n"
|
15
29
|
email: krada@gmx.net
|
@@ -23,20 +37,26 @@ files:
|
|
23
37
|
- bin/ccl
|
24
38
|
- bin/ccl~
|
25
39
|
- lib/array.rb
|
40
|
+
- lib/changelog.rb
|
41
|
+
- lib/changelog.rb~
|
26
42
|
- lib/changelog_filter.rb
|
27
43
|
- lib/commit_changelog.rb
|
28
|
-
- lib/
|
29
|
-
- lib/create_changelog.rb~
|
44
|
+
- lib/commit_changelog.rb~
|
30
45
|
- lib/git.rb
|
46
|
+
- lib/git.rb~
|
31
47
|
- lib/tag.rb
|
48
|
+
- lib/tag.rb~
|
32
49
|
- lib/tag_list.rb
|
50
|
+
- lib/tag_list.rb~
|
33
51
|
- lib/version.rb
|
34
52
|
- lib/version.rb~
|
35
53
|
homepage: https://github.com/bovender/create-changelog
|
36
54
|
licenses:
|
37
55
|
- Apache License version 2
|
38
56
|
metadata: {}
|
39
|
-
post_install_message:
|
57
|
+
post_install_message: |
|
58
|
+
create_changelog version 1.3.0 has been installed.
|
59
|
+
For usage information, type ccl -h
|
40
60
|
rdoc_options: []
|
41
61
|
require_paths:
|
42
62
|
- lib
|
@@ -52,8 +72,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
72
|
version: '0'
|
53
73
|
requirements: []
|
54
74
|
rubyforge_project:
|
55
|
-
rubygems_version: 2.
|
75
|
+
rubygems_version: 2.4.5
|
56
76
|
signing_key:
|
57
77
|
specification_version: 4
|
58
78
|
summary: Creates end-user-friendly changelog from git messages.
|
59
79
|
test_files: []
|
80
|
+
has_rdoc:
|
data/lib/create_changelog.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
# changelog.rb, part of Create-changelog
|
2
|
-
# Copyright 2015 Daniel Kraus
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
require_relative './commit_changelog.rb'
|
15
|
-
require_relative './tag_list.rb'
|
16
|
-
require_relative './tag.rb'
|
17
|
-
|
18
|
-
# Central class that puts together the changelog.
|
19
|
-
class Changelog
|
20
|
-
# Heading for the most recent changes.
|
21
|
-
attr_writer :recent_changes_heading
|
22
|
-
|
23
|
-
def initialize
|
24
|
-
@recent_changes_heading = "Unpublished changes"
|
25
|
-
end
|
26
|
-
|
27
|
-
# Generates a decorated changelog.
|
28
|
-
def generate(exclude_recent = false)
|
29
|
-
# Traverse tags
|
30
|
-
tags = TagList.new(!exclude_recent)
|
31
|
-
output = String.new
|
32
|
-
tags.list.each_cons(2) do |current_tag, previous_tag|
|
33
|
-
output << generate_for(current_tag, previous_tag)
|
34
|
-
end
|
35
|
-
output
|
36
|
-
end
|
37
|
-
|
38
|
-
# Returns a simple, undecorated list of changelog entries
|
39
|
-
# since the most recent tag.
|
40
|
-
def generate_recent
|
41
|
-
tags = TagList.new
|
42
|
-
log = CommitChangelog.new(tags.list[0], tags.list[1])
|
43
|
-
log.changelog
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def generate_for(current_tag, previous_tag)
|
49
|
-
tag = Tag.new(current_tag)
|
50
|
-
commit_changelog = CommitChangelog.new(current_tag, previous_tag)
|
51
|
-
|
52
|
-
# Combine changelog entries from tag annotation and commit messages
|
53
|
-
if tag.changelog
|
54
|
-
combined_changelog = tag.changelog.concat(commit_changelog.changelog)
|
55
|
-
else
|
56
|
-
combined_changelog = commit_changelog.changelog
|
57
|
-
end
|
58
|
-
combined_changelog.uniq! if combined_changelog
|
59
|
-
|
60
|
-
output = String.new
|
61
|
-
tag.heading = @recent_changes_heading unless tag.heading
|
62
|
-
if tag.heading
|
63
|
-
output << tag.heading + " (#{tag.date})\n"
|
64
|
-
output << "=" * 72 + "\n"
|
65
|
-
end
|
66
|
-
output << tag.text.join("\n") + "\n" if tag.text
|
67
|
-
output << combined_changelog.join("\n") + "\n" if combined_changelog
|
68
|
-
output << end_separator if tag.heading or tag.text or combined_changelog
|
69
|
-
output
|
70
|
-
end
|
71
|
-
|
72
|
-
def end_separator
|
73
|
-
"\n" + ("* " * 36) +"\n\n\n"
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# vim: nospell
|
data/lib/create_changelog.rb~
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
# changelog.rb, part of Create-changelog
|
2
|
-
# Copyright 2015 Daniel Kraus
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
require_relative './commit_changelog.rb'
|
15
|
-
require_relative './tag_list.rb'
|
16
|
-
require_relative './tag.rb'
|
17
|
-
|
18
|
-
# Central class that puts together the changelog.
|
19
|
-
class Changelog
|
20
|
-
# Heading for the most recent changes.
|
21
|
-
attr_writer :recent_changes_heading
|
22
|
-
|
23
|
-
def initialize
|
24
|
-
@recent_changes_heading = "Unpublished changes"
|
25
|
-
end
|
26
|
-
|
27
|
-
# Generates a decorated changelog.
|
28
|
-
def generate(exclude_recent = false)
|
29
|
-
# Traverse tags
|
30
|
-
tags = TagList.new(!exclude_recent)
|
31
|
-
output = String.new
|
32
|
-
tags.list.each_cons(2) do |current_tag, previous_tag|
|
33
|
-
output << generate_for(current_tag, previous_tag)
|
34
|
-
end
|
35
|
-
output
|
36
|
-
end
|
37
|
-
|
38
|
-
# Returns a simple, undecorated list of changelog entries
|
39
|
-
# since the most recent tag.
|
40
|
-
def generate_recent
|
41
|
-
tags = TagList.new
|
42
|
-
log = CommitChangelog.new(tags.list[0], tags.list[1])
|
43
|
-
log.changelog.inspect
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def generate_for(current_tag, previous_tag)
|
49
|
-
tag = Tag.new(current_tag)
|
50
|
-
commit_changelog = CommitChangelog.new(current_tag, previous_tag)
|
51
|
-
|
52
|
-
# Combine changelog entries from tag annotation and commit messages
|
53
|
-
if tag.changelog
|
54
|
-
combined_changelog = tag.changelog.concat(commit_changelog.changelog)
|
55
|
-
else
|
56
|
-
combined_changelog = commit_changelog.changelog
|
57
|
-
end
|
58
|
-
combined_changelog.uniq! if combined_changelog
|
59
|
-
|
60
|
-
output = String.new
|
61
|
-
tag.heading = @recent_changes_heading unless tag.heading
|
62
|
-
if tag.heading
|
63
|
-
output << tag.heading + " (#{tag.date})\n"
|
64
|
-
output << "=" * 72 + "\n"
|
65
|
-
end
|
66
|
-
output << tag.text.join("\n") + "\n" if tag.text
|
67
|
-
output << combined_changelog.join("\n") + "\n" if combined_changelog
|
68
|
-
output << end_separator if tag.heading or tag.text or combined_changelog
|
69
|
-
output
|
70
|
-
end
|
71
|
-
|
72
|
-
def end_separator
|
73
|
-
"\n" + ("* " * 36) +"\n\n\n"
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# vim: nospell
|