create_changelog 1.2.0 → 1.3.0
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.
- 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
|
+
[](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
|