create_changelog 1.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bd381224eb8e14e9bdbb5b5b58dedb315b2390ab
4
+ data.tar.gz: 3713419603968048a91c5bb5eb02f0df554b263e
5
+ SHA512:
6
+ metadata.gz: 1a38fea06c029efe529b4defb5cab2a772df00a554ea5f27eef7250c278eb46e5e686fe06b5b8a33d9c7fd09d8e67b0b6d624e2993262d3fc7785b28801c0837
7
+ data.tar.gz: a9dc791d30ca360cbf964a8c303da4c9f44e152c858fc12c76c7732b6ddc747b87c7a87fdbb144e8fb1729e06296d0b5163501804f53a512dd17b20eebb8639e
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ Version 1.1.0 (2015-01-18)
2
+ ========================================================================
3
+
4
+ - CHANGED: Accept dashes in addition to asterisks in changelog lines.
5
+ - NEW: Create gem.
6
+
7
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8
+
9
+
10
+ Version 1.0.0 (2015-01-18)
11
+ ========================================================================
12
+
13
+
14
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
15
+
16
+
data/README.md ADDED
@@ -0,0 +1,146 @@
1
+ create-changelog
2
+ ================
3
+
4
+ Ruby program with command-line interface that creates a changelog from
5
+ log lines in a git repository that can be read and understood by end
6
+ users.
7
+
8
+ There are several approaches to creating changelog files from git
9
+ commits (e.g., [gitchangelog][], [gitlog-to-changelog][gl2cl] and many
10
+ more). None of these quite fit my needs, so I decided to create my own
11
+ tool.
12
+
13
+ What's special about my approach is that the changelog information is
14
+ not taken from every commit, but from specially marked lines in the
15
+ commit messages and tag annotations. Changelog lines must comply with
16
+ the format:
17
+
18
+ - [KEYWORD]: [TEXT]
19
+
20
+ Where `[KEYWORD]` may be any keyword of your liking, such as "NEW",
21
+ "FIX", and so on. (I am planning to predefine these keywords in a later
22
+ version.) `[TEXT]` is an explanation of the change. _Note that the
23
+ program currently operates on single lines, so it is not possible to
24
+ have `[TEXT]` span several lines._
25
+
26
+ The reason why I chose to have special changelog lines rather than
27
+ commit subjects is that commits are rather technical, but I want to have
28
+ a changelog that can be read by 'normal' end users.
29
+
30
+
31
+ Usage
32
+ -----
33
+
34
+ ### Creating log entries
35
+ When committing, add a line that fits the above definition to the commit
36
+ message, e.g.
37
+
38
+ Implement Backup class.
39
+
40
+ - NEW: Ability to back up the files.
41
+
42
+ Create annotated tags to identify new versions:
43
+
44
+ Version 7.0.0-alpha.3
45
+
46
+ This version adds a new backup feature and fixes several bugs.
47
+
48
+ If you wish, you can include additional changelog entries in the tag
49
+ annotation. These may even be the same that you used for the commit
50
+ messages (and this tool provides a way to filter the commit messages for
51
+ just these lines). The tool ensures that there are no duplicate
52
+ changelog entries.
53
+
54
+ Version 7.0.0-alpha.3
55
+
56
+ This version adds a new backup feature and fixes several bugs.
57
+
58
+ - NEW: Ability to back up the files.
59
+
60
+
61
+ ### Generating the log
62
+
63
+ To generate a complete change log, simply run the tool in the directory
64
+ of the git repository, or indicate a working directory:
65
+
66
+ ccl.rb -d /home/me/my/repository
67
+
68
+ The output will be in markdown format. If you wish, you can further
69
+ process it using tools like [pandoc][] for example. Of course, it is
70
+ also possible to incorporate the command in the content files for a
71
+ static site generator such as [nanoc][].
72
+
73
+ If you want to track your log in the git repository, you probably will
74
+ not yet have an annotated tag for the version you are preparing. In this
75
+ case, the tool will use "Unpublished changes" as the heading for the
76
+ latest changes. To use the version number that you are about to use in
77
+ the tag, call the tool with an optional argument:
78
+
79
+ ccl.rb 7.0.0-alpha.4
80
+
81
+ Be aware that currently, the date of the most recent commit (that HEAD
82
+ points to) will be appended to the heading.
83
+
84
+ To exclude recent changes that were logged since the last tag:
85
+
86
+ ccl.rb --no-recent
87
+ ccl.rb -n
88
+
89
+ To just see the (undecorated) changelog entries since the last tag, use:
90
+
91
+ ccl.rb --recent
92
+ ccl.rb -r
93
+
94
+ This can be handy if you want to add a log of recent changes to your tag
95
+ annotation. For example, using the Vim text editor, issue:
96
+
97
+ :r!ccl.rb -r
98
+
99
+ The tool will make sure that no changelog lines are duplicated.
100
+
101
+
102
+ Changelog format
103
+ ----------------
104
+
105
+ The changelog format resembles the [suggestions][kacl] made by Olivier
106
+ Lacan. I have not yet have the time to implement automatic generation of
107
+ subheadings. Maybe I'll add the feature in the future.
108
+
109
+
110
+ Live example
111
+ ------------
112
+
113
+ <http://xltoolbox.sf.net/changelog-ng>
114
+
115
+
116
+ Code
117
+ ----
118
+
119
+ To understand the code, you can run `rdoc` in the repository's
120
+ directory. The resulting `doc` subdirectory will be ignored by Git.
121
+
122
+
123
+ License
124
+ -------
125
+
126
+ Copyright 2015 Daniel Kraus
127
+ Licensed under the Apache License, Version 2.0 (the "License");
128
+ you may not use this file except in compliance with the License.
129
+ You may obtain a copy of the License at
130
+
131
+ http://www.apache.org/licenses/LICENSE-2.0
132
+
133
+ Unless required by applicable law or agreed to in writing, software
134
+ distributed under the License is distributed on an "AS IS" BASIS,
135
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136
+ See the License for the specific language governing permissions and
137
+ limitations under the License.
138
+
139
+ [gitchangelog]: https://pypi.python.org/pypi/gitchangelog
140
+ [gl2cl]: https://github.com/manuelbua/gitver/blob/master/gitlog-to-changelog
141
+ [gnu-changelog]: http://www.gnu.org/prep/standards/html_node/Change-Logs.html
142
+ [pandoc]: http://johnmacfarlane.net/pandoc
143
+ [nanoc]: http://nanoc.ws
144
+ [kacl]: http://keepachangelog.com
145
+
146
+ <!-- vim: set tw=72 : -->
data/bin/ccl ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+ # Create-changelog
3
+ # Copyright 2015 Daniel Kraus
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # Filters the git log of the repository in the current directory
17
+ # for unique lines that match the pattern
18
+ # * [KEYWORD]: [DESCRIPTION]
19
+ # The filtered lines are sorted and written to standard out.
20
+
21
+ require 'optparse'
22
+ require_relative '../lib/create_changelog.rb'
23
+ require_relative '../lib/git.rb'
24
+ require_relative '../lib/version.rb'
25
+
26
+ def main
27
+ options = {}
28
+ working_dir = Dir.pwd
29
+ option_parser = OptionParser.new do |opts|
30
+ exe_name = File.basename($PROGRAM_NAME)
31
+ opts.banner = "#{exe_name} version #{CreateChangelog::VERSION}\n"
32
+ opts.banner += "Creates changelog from log entries in git log\n"
33
+ opts.banner += "Usage: #{exe_name} [options] [current_version]"
34
+ opts.on("-r", "--recent",
35
+ "Include only most recent changes") do
36
+ abort "FATAL: Cannot combine --recent and --no-recent" if options[:no_recent]
37
+ options[:only_recent] = true
38
+ end
39
+ opts.on("-n", "--no-recent",
40
+ "Exclude the most recent changes (from untagged commits)") do
41
+ abort "FATAL: Cannot combine --recent and --no-recent" if options[:recent]
42
+ options[:no_recent] = true
43
+ end
44
+ opts.on("-d WORKING_DIR", "--dir WORKING_DIR",
45
+ "Use alternate working directory") do |dir|
46
+ working_dir = dir
47
+ end
48
+ end
49
+ option_parser.parse!
50
+
51
+ Dir.chdir(working_dir) do
52
+ abort "FATAL: Not a git repository." unless Git.is_git_repository?
53
+
54
+ change_log = Changelog.new
55
+ change_log.recent_changes_heading = ARGV[0] unless ARGV.empty?
56
+ if options[:only_recent]
57
+ puts change_log.generate_recent
58
+ else
59
+ puts change_log.generate(options[:no_recent])
60
+ end
61
+ end
62
+ end
63
+
64
+ main
65
+
66
+ # vim: nospell
data/bin/ccl~ ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+ # Create-changelog
3
+ # Copyright 2015 Daniel Kraus
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # Filters the git log of the repository in the current directory
17
+ # for unique lines that match the pattern
18
+ # * [KEYWORD]: [DESCRIPTION]
19
+ # The filtered lines are sorted and written to standard out.
20
+
21
+ require 'optparse'
22
+ require_relative '../lib/changelog.rb'
23
+ require_relative '../lib/git.rb'
24
+ require_relative '../lib/version.rb'
25
+
26
+ def main
27
+ options = {}
28
+ working_dir = Dir.pwd
29
+ option_parser = OptionParser.new do |opts|
30
+ exe_name = File.basename($PROGRAM_NAME)
31
+ opts.banner = "#{exe_name} version #{CreateChangelog::VERSION}\n"
32
+ opts.banner += "Creates changelog from log entries in git log\n"
33
+ opts.banner += "Usage: #{exe_name} [options] [current_version]"
34
+ opts.on("-r", "--recent",
35
+ "Include only most recent changes") do
36
+ abort "FATAL: Cannot combine --recent and --no-recent" if options[:no_recent]
37
+ options[:only_recent] = true
38
+ end
39
+ opts.on("-n", "--no-recent",
40
+ "Exclude the most recent changes (from untagged commits)") do
41
+ abort "FATAL: Cannot combine --recent and --no-recent" if options[:recent]
42
+ options[:no_recent] = true
43
+ end
44
+ opts.on("-d WORKING_DIR", "--dir WORKING_DIR",
45
+ "Use alternate working directory") do |dir|
46
+ working_dir = dir
47
+ end
48
+ end
49
+ option_parser.parse!
50
+
51
+ Dir.chdir(working_dir) do
52
+ abort "FATAL: Not a git repository." unless Git.is_git_repository?
53
+
54
+ change_log = Changelog.new
55
+ change_log.recent_changes_heading = ARGV[0] unless ARGV.empty?
56
+ if options[:only_recent]
57
+ puts change_log.generate_recent
58
+ else
59
+ puts change_log.generate(options[:no_recent])
60
+ end
61
+ end
62
+ end
63
+
64
+ main
65
+
66
+ # vim: nospell
data/lib/array.rb ADDED
@@ -0,0 +1,18 @@
1
+ # Removes common indentation from an array of strings
2
+ class Array
3
+ def remove_indent
4
+ lines_with_indent = self.select do |line|
5
+ line.size > 0
6
+ end
7
+ indents = lines_with_indent.map do |line|
8
+ match = line.match(/^( +)([^ ]|$)+/)
9
+ match ? match[1].size : 0
10
+ end
11
+ indent = indents.min
12
+ self.map do |line|
13
+ line[indent..-1]
14
+ end
15
+ end
16
+ end
17
+
18
+ # vim: nospell
@@ -0,0 +1,57 @@
1
+ # changelog_filter.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
+
15
+ require_relative 'array'
16
+
17
+ # Filters a text or array for changelog entries.
18
+ class ChangelogFilter
19
+ # Factory method that creates an instance given a text string
20
+ def self.FromString(string)
21
+ unless string.is_a?(String)
22
+ fail "Must call this factory with String, not " + string.class.to_s
23
+ end
24
+ self.FromArray(string.chomp.split("\n"))
25
+ end
26
+
27
+ # Factory method that creates an instance given an array of strings
28
+ def self.FromArray(ary)
29
+ unless ary.is_a?(Array)
30
+ fail "Must call this factory with Array, not " + ary.class.to_s
31
+ end
32
+ filter = ChangelogFilter.new
33
+ log, filter.other_text = ary.partition do |line|
34
+ line.match(pattern)
35
+ end
36
+ filter.changelog = log.uniq.sort.remove_indent if log.length > 0
37
+ filter
38
+ end
39
+
40
+ # Returns the grep string that matches changelog entries.
41
+ def self.pattern
42
+ '\s*[*-]\s+[^:]+:\s'
43
+ end
44
+
45
+ # An array of changelog entries.
46
+ attr_accessor :changelog
47
+
48
+ # An array of text lines that are not changelog entries.
49
+ attr_accessor :other_text
50
+
51
+ private
52
+
53
+ def initialize
54
+ end
55
+ end
56
+
57
+ # vim: nospell
@@ -0,0 +1,57 @@
1
+ # changelog_filter.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
+
15
+ require_relative 'array'
16
+
17
+ # Filters a text or array for changelog entries.
18
+ class ChangelogFilter
19
+ # Factory method that creates an instance given a text string
20
+ def self.FromString(string)
21
+ unless string.is_a?(String)
22
+ fail "Must call this factory with String, not " + string.class.to_s
23
+ end
24
+ self.FromArray(string.chomp.split("\n"))
25
+ end
26
+
27
+ # Factory method that creates an instance given an array of strings
28
+ def self.FromArray(ary)
29
+ unless ary.is_a?(Array)
30
+ fail "Must call this factory with Array, not " + ary.class.to_s
31
+ end
32
+ filter = ChangelogFilter.new
33
+ log, filter.other_text = ary.partition do |line|
34
+ line.match(pattern)
35
+ end
36
+ filter.changelog = log.uniq.sort.remove_indent if log.length > 0
37
+ filter
38
+ end
39
+
40
+ # Returns the grep string that matches changelog entries.
41
+ def self.pattern
42
+ '\s*\*\s+[^:]+:\s'
43
+ end
44
+
45
+ # An array of changelog entries.
46
+ attr_accessor :changelog
47
+
48
+ # An array of text lines that are not changelog entries.
49
+ attr_accessor :other_text
50
+
51
+ private
52
+
53
+ def initialize
54
+ end
55
+ end
56
+
57
+ # vim: nospell
@@ -0,0 +1,31 @@
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
+ # Contains changelog entries of the commits.
19
+ attr_reader :changelog
20
+
21
+ # Instantiates an object containing changelog entries between
22
+ # two git commits.
23
+ def initialize(to_commit, from_commit)
24
+ pattern = ChangelogFilter.pattern
25
+ messages = Git.get_filtered_messages(from_commit, to_commit, pattern)
26
+ filter = ChangelogFilter.FromString(messages)
27
+ @changelog = filter.changelog
28
+ end
29
+ end
30
+
31
+ # vim: nospell
@@ -0,0 +1,74 @@
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
+ end
42
+
43
+ private
44
+
45
+ def generate_for(current_tag, previous_tag)
46
+ tag = Tag.new(current_tag)
47
+ commit_changelog = CommitChangelog.new(current_tag, previous_tag)
48
+
49
+ # Combine changelog entries from tag annotation and commit messages
50
+ if tag.changelog
51
+ combined_changelog = tag.changelog.concat(commit_changelog.changelog)
52
+ else
53
+ combined_changelog = commit_changelog.changelog
54
+ end
55
+ combined_changelog.uniq! if combined_changelog
56
+
57
+ output = String.new
58
+ tag.heading = @recent_changes_heading unless tag.heading
59
+ if tag.heading
60
+ output << tag.heading + " (#{tag.date})\n"
61
+ output << "=" * 72 + "\n"
62
+ end
63
+ output << tag.text.join("\n") + "\n" if tag.text
64
+ output << combined_changelog.join("\n") + "\n" if combined_changelog
65
+ output << end_separator if tag.heading or tag.text or combined_changelog
66
+ output
67
+ end
68
+
69
+ def end_separator
70
+ "\n" + ("* " * 36) +"\n\n\n"
71
+ end
72
+ end
73
+
74
+ # vim: nospell
data/lib/git.rb ADDED
@@ -0,0 +1,60 @@
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
+ # Retrieves the first 99 lines of the annotation of a tag.
27
+ def self.get_tag_annotation(tag)
28
+ test_tag tag
29
+ `git tag -l -n99 #{tag}`.rstrip
30
+ end
31
+
32
+ # Retrieves the date of a tag
33
+ def self.get_tag_date(tag)
34
+ test_tag tag
35
+ `git log -1 --format=format:%ai #{tag}`
36
+ end
37
+
38
+ # Retrieves commit messages and filters them
39
+ # Todo: Armor this against code injection!
40
+ def self.get_filtered_messages(from_commit, to_commit, filter)
41
+ `git log #{from_commit}..#{to_commit} -E --grep='#{filter}' --format=%b`
42
+ end
43
+
44
+ @@tags = nil
45
+
46
+ # Ensures lazy loading of the tag list to enable calling code
47
+ # to change the working directory first.
48
+ def self.tags
49
+ @@tags = TagList.new unless @@tags
50
+ @@tags
51
+ end
52
+
53
+ # Tests if the given tag exists and fails if it doesn't
54
+ def self.test_tag(tag)
55
+ fail "Invalid tag: #{tag}" unless tags.list.include?(tag)
56
+ end
57
+ private_class_method :test_tag, :tags
58
+ end
59
+
60
+ # vim: nospell
data/lib/git.rb~ ADDED
@@ -0,0 +1,58 @@
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
+ # Retrieves the first 99 lines of the annotation of a tag.
27
+ def self.get_tag_annotation(tag)
28
+ test_tag tag
29
+ `git tag -l -n99 #{tag}`.rstrip
30
+ end
31
+
32
+ # Retrieves the date of a tag
33
+ def self.get_tag_date(tag)
34
+ test_tag tag
35
+ `git log -1 --format=format:%ai #{tag}`
36
+ end
37
+
38
+ # Retrieves commit messages and filters them
39
+ # Todo: Armor this against code injection!
40
+ def self.get_filtered_messages(from_commit, to_commit, filter)
41
+ `git log #{from_commit}..#{to_commit} -E --grep='#{filter}' --format=%b`
42
+ end
43
+
44
+ @@tags = nil
45
+
46
+ def self.tags
47
+ @@tags = TagList.new unless @@tags
48
+ @@tags
49
+ end
50
+
51
+ # Tests if the given tag exists and fails if it doesn't
52
+ def self.test_tag(tag)
53
+ fail "Invalid tag: #{tag}" unless tags.list.include?(tag)
54
+ end
55
+ private_class_method :test_tag, :tags
56
+ end
57
+
58
+ # vim: nospell
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
46
+ @changelog = filter.changelog
47
+ end
48
+ end
49
+ end
50
+
51
+ # vim: nospell
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 ADDED
@@ -0,0 +1,3 @@
1
+ module CreateChangelog
2
+ VERSION = '1.1.0'
3
+ end
data/lib/version.rb~ ADDED
@@ -0,0 +1,3 @@
1
+ module CreateChangelog
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: create_changelog
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Kraus
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: "\t\tRuby program with command-line interface that creates a changelog
14
+ from log\n\t\tlines in a git repository that can be read and understood by end users.\n"
15
+ email: krada@gmx.net
16
+ executables:
17
+ - ccl
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - CHANGELOG.md
22
+ - README.md
23
+ - bin/ccl
24
+ - bin/ccl~
25
+ - lib/array.rb
26
+ - lib/changelog_filter.rb
27
+ - lib/changelog_filter.rb~
28
+ - lib/commit_changelog.rb
29
+ - lib/create_changelog.rb
30
+ - lib/git.rb
31
+ - lib/git.rb~
32
+ - lib/tag.rb
33
+ - lib/tag_list.rb
34
+ - lib/version.rb
35
+ - lib/version.rb~
36
+ homepage: https://github.com/bovender/create-changelog
37
+ licenses:
38
+ - Apache License version 2
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 2.2.2
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Creates end-user-friendly changelog from git messages.
60
+ test_files: []