tag-changelog 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9293d2c322efcd8fb7411c8bcb7c47d161b7a985
4
+ data.tar.gz: 1569037ac2782b2b24564335f6e0515f52dce1d6
5
+ SHA512:
6
+ metadata.gz: 364e78e00b586099fe42fb690fd0968ac0c56de31cf417d13ee07308f8619e3eeb57d20598eb1b3cad49a9f9a6dbe66b8d42f2a066b1eb032ad879bba2a581b9
7
+ data.tar.gz: 5ef46f7c023d99bdafc4598313782aeaf0d36cda7afd731424af110d8d28312a21ec3e7bec451f639df1c391a9f66af67ef04a8d53c9eaa4f7df7aada613a2ae
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ = changelog
2
+
3
+ Generate this with
4
+ changelog rdoc
5
+ After you have described your command line interface
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,68 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tag-changelog (0.1.0)
5
+ gli (= 2.17.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ aruba (0.14.3)
11
+ childprocess (~> 0.8.0)
12
+ contracts (~> 0.9)
13
+ cucumber (>= 1.3.19)
14
+ ffi (~> 1.9.10)
15
+ rspec-expectations (>= 2.99)
16
+ thor (~> 0.19)
17
+ backports (3.11.1)
18
+ builder (3.2.3)
19
+ childprocess (0.8.0)
20
+ ffi (~> 1.0, >= 1.0.11)
21
+ coderay (1.1.2)
22
+ contracts (0.16.0)
23
+ cucumber (3.1.0)
24
+ builder (>= 2.1.2)
25
+ cucumber-core (~> 3.1.0)
26
+ cucumber-expressions (~> 5.0.4)
27
+ cucumber-wire (~> 0.0.1)
28
+ diff-lcs (~> 1.3)
29
+ gherkin (~> 5.0)
30
+ multi_json (>= 1.7.5, < 2.0)
31
+ multi_test (>= 0.1.2)
32
+ cucumber-core (3.1.0)
33
+ backports (>= 3.8.0)
34
+ cucumber-tag_expressions (~> 1.1.0)
35
+ gherkin (>= 5.0.0)
36
+ cucumber-expressions (5.0.13)
37
+ cucumber-tag_expressions (1.1.1)
38
+ cucumber-wire (0.0.1)
39
+ diff-lcs (1.3)
40
+ ffi (1.9.21)
41
+ gherkin (5.0.0)
42
+ gli (2.17.1)
43
+ method_source (0.9.0)
44
+ multi_json (1.13.1)
45
+ multi_test (0.1.2)
46
+ pry (0.11.3)
47
+ coderay (~> 1.1.0)
48
+ method_source (~> 0.9.0)
49
+ rake (12.3.0)
50
+ rdoc (6.0.1)
51
+ rspec-expectations (3.7.0)
52
+ diff-lcs (>= 1.2.0, < 2.0)
53
+ rspec-support (~> 3.7.0)
54
+ rspec-support (3.7.1)
55
+ thor (0.20.0)
56
+
57
+ PLATFORMS
58
+ ruby
59
+
60
+ DEPENDENCIES
61
+ aruba
62
+ pry
63
+ rake
64
+ rdoc
65
+ tag-changelog!
66
+
67
+ BUNDLED WITH
68
+ 1.13.6
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # tag-changelog
2
+
3
+ Tool to generate changelog based on Parallel6 specs
4
+
5
+ #### NAME
6
+ tag-changelog - Tool to generate changelog based on Parallel6 specs
7
+
8
+ #### SYNOPSIS
9
+ tag-changelog [global options] command [command options] [arguments...]
10
+
11
+ #### VERSION
12
+ 0.0.1
13
+
14
+ #### GLOBAL OPTIONS
15
+ --help - Show this message
16
+ --version - Display the program version
17
+
18
+ #### COMMANDS
19
+ generate - Generate changelog and write to CHANGELOG.md (default).
20
+ help - Shows a list of commands or help for one command
21
+
22
+
23
+ ## Usage
24
+
25
+ All you need to do is cd into project's directory where you need to generate
26
+ changelog and run:
27
+
28
+ ```
29
+ $ tag-changelog generate
30
+ ```
31
+
32
+ This will execute the `generate` command with the default params. Please see below
33
+ for a list of options you can pass to the command.
34
+
35
+ #### generate command options
36
+ -c, --config=file - Configuration file to categorize commit messages in YML format. Must be an absolute path. (default: gem's own config.yml)
37
+ -d, --dir=directory - Git repository directory (must be an absolute path). Defaults to working directory. (default: current working directory)
38
+ -f, --filter=regexp - Regexp to categorize commits from git log. (default: (\[+\s?+[cfbhrCFBHR]{1}+\s?+\]))
39
+ --[no-]group - Group commit messages in categories (defined in configuration file). (default: enabled)
40
+ --[no-]head - Include HEAD as a tag. Useful when new tag is not released yet (as a preview). Can be disabled. (default: enabled)
41
+ -o, --output=file - Output destination. (default: CHANGELOG.md)
42
+ --[no-]pull-requests-only - Only list merged pull requests. Can be disabled to list all commits. (default: enabled)
43
+ -s, --skip=tag_list - Skip tags (may be used more than once, default: none)
data/Rakefile ADDED
@@ -0,0 +1,44 @@
1
+ require 'rake/clean'
2
+ require 'rubygems'
3
+ require 'rubygems/package_task'
4
+ require 'rdoc/task'
5
+ require 'cucumber'
6
+ require 'cucumber/rake/task'
7
+ Rake::RDocTask.new do |rd|
8
+ rd.main = "README.rdoc"
9
+ rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
10
+ rd.title = 'Your application title'
11
+ end
12
+
13
+ spec = eval(File.read('changelog.gemspec'))
14
+
15
+ Gem::PackageTask.new(spec) do |pkg|
16
+ end
17
+ CUKE_RESULTS = 'results.html'
18
+ CLEAN << CUKE_RESULTS
19
+ desc 'Run features'
20
+ Cucumber::Rake::Task.new(:features) do |t|
21
+ opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
22
+ opts += " --tags #{ENV['TAGS']}" if ENV['TAGS']
23
+ t.cucumber_opts = opts
24
+ t.fork = false
25
+ end
26
+
27
+ desc 'Run features tagged as work-in-progress (@wip)'
28
+ Cucumber::Rake::Task.new('features:wip') do |t|
29
+ tag_opts = ' --tags ~@pending'
30
+ tag_opts = ' --tags @wip'
31
+ t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}"
32
+ t.fork = false
33
+ end
34
+
35
+ task :cucumber => :features
36
+ task 'cucumber:wip' => 'features:wip'
37
+ task :wip => 'features:wip'
38
+ require 'rake/testtask'
39
+ Rake::TestTask.new do |t|
40
+ t.libs << "test"
41
+ t.test_files = FileList['test/*_test.rb']
42
+ end
43
+
44
+ task :default => [:test,:features]
data/bin/tag-changelog ADDED
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gli'
3
+ # begin # XXX: Remove this begin/rescue before distributing your app
4
+ require 'tag_changelog'
5
+ # rescue LoadError
6
+ # STDERR.puts "In development, you need to use `bundle exec bin/changelog` to run your app"
7
+ # STDERR.puts "At install-time, RubyGems will make sure lib, etc. are in the load path"
8
+ # STDERR.puts "Feel free to remove this message from bin/changelog now"
9
+ # exit 64
10
+ # end
11
+
12
+ include GLI::App
13
+
14
+ program_desc 'Tool to generate changelog based on Parallel6 specs'
15
+
16
+ version TagChangelog::VERSION
17
+
18
+ subcommand_option_handling :normal
19
+ arguments :strict
20
+
21
+ desc 'Generate changelog and write to CHANGELOG.md (default).'
22
+ command :generate do |c|
23
+ c.desc 'Configuration file to categorize commit messages in YML format. Must be an absolute path.'
24
+ c.default_value File.expand_path("../../lib/tag_changelog/templates/config.yml", __FILE__)
25
+ c.arg_name 'file'
26
+ c.flag [:c, :config]
27
+
28
+ c.desc 'Git repository directory (must be an absolute path). Defaults to working directory.'
29
+ c.default_value Dir.pwd
30
+ c.arg_name 'directory'
31
+ c.flag [:d, :dir]
32
+
33
+ c.desc 'Output destination.'
34
+ c.default_value 'CHANGELOG.md'
35
+ c.arg_name 'file'
36
+ c.flag [:o, :output]
37
+
38
+ c.desc 'Regexp to categorize commits from git log.'
39
+ c.default_value '(\[+\s?+[cfbhrCFBHR]{1}+\s?+\])'
40
+ c.arg_name 'regexp'
41
+ c.flag [:f, :filter]
42
+
43
+ c.desc 'Skip tags'
44
+ c.arg_name 'tag_list'
45
+ c.flag [:s, :skip], multiple: true
46
+
47
+ c.desc 'Group commit messages in categories (defined in configuration file).'
48
+ c.default_value true
49
+ c.switch "group"
50
+
51
+ c.desc 'Include HEAD as a tag. Useful when new tag is not released yet (as a preview). Can be disabled.'
52
+ c.default_value true
53
+ c.switch "head"
54
+
55
+ c.desc 'Only list merged pull requests. Can be disabled to list all commits.'
56
+ c.default_value true
57
+ c.switch "pull-requests-only"
58
+
59
+ c.action do |global_options,options,args|
60
+ # Your command logic here
61
+ # If you have any errors, just raise them
62
+ # raise "that command made no sense"
63
+ Dir.chdir(options[:dir]) do
64
+ puts "Changelog will be written to: #{[options[:dir], options[:output]].join('/')}"
65
+ TagChangelog::Generate.run(options)
66
+ end
67
+ end
68
+ end
69
+
70
+ pre do |global,command,options,args|
71
+ # Pre logic here
72
+ # Return true to proceed; false to abort and not call the
73
+ # chosen command
74
+ # Use skips_pre before a command to skip this block
75
+ # on that command only
76
+ # true
77
+ abort "FATAL: Git is not installed." unless Git::Git.is_installed?
78
+ Dir.chdir(options[:dir]) do
79
+ abort "FATAL: Not a git repository." unless Git::Git.is_git_repository?
80
+ abort "FATAL: No commits in git repository." if Git::Git.is_empty_repository?
81
+ true
82
+ end
83
+ end
84
+
85
+ post do |global,command,options,args|
86
+ # Post logic here
87
+ # Use skips_post before a command to skip this
88
+ # block on that command only
89
+ end
90
+
91
+ on_error do |exception|
92
+ # Error logic here
93
+ # return false to skip default error handling
94
+ true
95
+ end
96
+
97
+ exit run(ARGV)
@@ -0,0 +1,8 @@
1
+ Feature: My bootstrapped app kinda works
2
+ In order to get going on coding my awesome app
3
+ I want to have aruba and cucumber setup
4
+ So I don't have to do it myself
5
+
6
+ Scenario: App just runs
7
+ When I get help for "changelog"
8
+ Then the exit status should be 0
@@ -0,0 +1,6 @@
1
+ When /^I get help for "([^"]*)"$/ do |app_name|
2
+ @app_name = app_name
3
+ step %(I run `#{app_name} help`)
4
+ end
5
+
6
+ # Add more step definitions here
@@ -0,0 +1,15 @@
1
+ require 'aruba/cucumber'
2
+
3
+ ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
4
+ LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
5
+
6
+ Before do
7
+ # Using "announce" causes massive warnings on 1.9.2
8
+ @puts = true
9
+ @original_rubylib = ENV['RUBYLIB']
10
+ ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
11
+ end
12
+
13
+ After do
14
+ ENV['RUBYLIB'] = @original_rubylib
15
+ end
@@ -0,0 +1,9 @@
1
+ require 'yaml'
2
+ require 'tag_changelog/version'
3
+
4
+ # Add requires for other files you add to your project here, so
5
+ # you just need to require this one file in your bin file
6
+ require 'tag_changelog/git/git'
7
+ require 'tag_changelog/git/tag_list'
8
+ require 'tag_changelog/git/tag'
9
+ require 'tag_changelog/generate'
@@ -0,0 +1,121 @@
1
+ # A class to manipulate output destination of changelog and to write its contents.
2
+ module TagChangelog
3
+ class Generate
4
+ def self.run(options)
5
+ new(options).run
6
+ end
7
+
8
+ def initialize(options = {})
9
+ @options = options
10
+ @output = open_output_file
11
+ @tags_list = build_tags_list(options)
12
+ @filter = Regexp.new(options[:filter], true)
13
+ @commit_messages_filter = set_commits_filter(options)
14
+ @group = options[:group]
15
+ end
16
+
17
+ def run
18
+ output << "# Changelog\n\n"
19
+ tags_list.each_cons(2) do |current_tag, previous_tag|
20
+ tag = Git::Tag.new(current_tag)
21
+ messages = get_commit_messages(previous_tag, current_tag)
22
+ output << "## #{tag.version}" + " (#{tag.date})\n"
23
+ output << messages.to_text
24
+ output << "\n"
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :options,
31
+ :output,
32
+ :tags_list,
33
+ :filter,
34
+ :commit_messages_filter,
35
+ :group
36
+
37
+ def output_file_exists?
38
+ File.exists?(options[:output])
39
+ end
40
+
41
+ def open_output_file
42
+ puts "#{options[:output]} doesn't exist in #{options[:dir]}... creating it" unless output_file_exists?
43
+ File.open(options[:output], "w+")
44
+ end
45
+
46
+ def build_tags_list(options)
47
+ Git::TagList.new(options[:head]).list.reject do |tag|
48
+ tag if options[:skip].include?(tag)
49
+ end
50
+ end
51
+
52
+ def set_commits_filter(options)
53
+ options["pull-requests-only"] ? 'Merge pull request' : nil
54
+ end
55
+
56
+ def get_commit_messages(previous_tag, current_tag)
57
+ messages = Git::Git.get_filtered_messages(previous_tag,
58
+ current_tag,
59
+ commit_messages_filter).split("\n")
60
+ # if not filtering merged pull requests only
61
+ # we need to remove the commit sha (first 9 chars in each row)
62
+ messages = messages.map { |msg| msg[10..-1] } unless commit_messages_filter
63
+ messages = categorize_messages(messages, build_categories) if group
64
+ messages = MessageList.new(messages, group)
65
+ end
66
+
67
+ def categorize_messages(messages, categories)
68
+ uncategorized = categories.detect { |cat| cat["header"] == "Uncategorized" }
69
+ messages.each do |msg|
70
+ matching_category = categories.detect do |category|
71
+ next unless category["filters"]
72
+ category["filters"].map { |ftr| msg.include?(ftr) }.include?(true)
73
+ end
74
+ if matching_category
75
+ msg = msg.gsub!(filter, matching_category["bullet"])
76
+ matching_category["messages"].push(msg)
77
+ else
78
+ uncategorized["messages"].push("* #{msg}")
79
+ end
80
+ end
81
+
82
+ categories
83
+ end
84
+
85
+ def build_categories
86
+ categories = YAML.load_file(options[:config])
87
+ categories.each { |category| category["messages"] = [] }
88
+ categories
89
+ end
90
+
91
+ class MessageList
92
+ attr_reader :messages, :grouped
93
+
94
+ def initialize(messages = [], grouped = true)
95
+ @messages = messages
96
+ @grouped = grouped
97
+ end
98
+
99
+ def to_text
100
+ if grouped
101
+ messages.map do |category|
102
+ category["messages"].any? ? print_category(category) : nil
103
+ end.reject(&:nil?).join("")
104
+ else
105
+ print_lines(messages).reject(&:nil?).join("")
106
+ end
107
+ end
108
+
109
+ def print_category(category)
110
+ [
111
+ "#### #{category['header']}",
112
+ print_lines(category["messages"]).join(""),
113
+ ].join("\n")
114
+ end
115
+
116
+ def print_lines(lines)
117
+ lines.map { |line| "#{line}\n" }
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,152 @@
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
+ module Git
18
+ class Git
19
+
20
+ # Determines whether Git is installed
21
+ #
22
+ # @return [bool]
23
+ # True if Git is installed, false if not.
24
+ #
25
+ def self.is_installed?
26
+ `git --version`
27
+ $? == 0
28
+ end
29
+
30
+ # Determines whether the (current) directory is a git repository
31
+ #
32
+ # @param [String] dir
33
+ # Directory to check; if nil, uses the current directory.
34
+ #
35
+ # @return [bool]
36
+ # True if the directory is a Git repository, false if not.
37
+ def self.is_git_repository?(dir = nil)
38
+ dir = Dir.pwd if dir.nil?
39
+ system("git status > /dev/null 2>&1")
40
+ $? == 0
41
+ end
42
+
43
+ # Determines if the repository in the current directory is empty.
44
+ #
45
+ def self.is_empty_repository?
46
+ `git show HEAD > /dev/null 2>&1`
47
+ $? != 0
48
+ end
49
+
50
+ # Retrieves the name of the current branch.
51
+ #
52
+ # @return [String]
53
+ # Current branch.
54
+ def self.current_branch
55
+ `git name-rev --name-only HEAD`.strip
56
+ end
57
+
58
+ # Launches the text editor that Git uses for commit messages,
59
+ # and passes file as a command line argument to it.
60
+ #
61
+ # @see https://github.com/git/git/blob/master/editor.c
62
+ # Git's editor.c on GitHub
63
+ #
64
+ # @param [String] file
65
+ # Filename to pass to the editor.
66
+ #
67
+ # @return [int]
68
+ # Exit code of the editor process, or false if no editor found.
69
+ #
70
+ def self.launch_editor(file)
71
+ # const char *editor = getenv("GIT_EDITOR");
72
+ editor = ENV['GIT_EDITOR']
73
+
74
+ # const char *terminal = getenv("TERM");
75
+ terminal = ENV['TERM'];
76
+
77
+ # int terminal_is_dumb = !terminal || !strcmp(terminal, "dumb");
78
+ terminal_is_dumb = !terminal || terminal == 'dumb'
79
+
80
+ # if (!editor && editor_program)
81
+ editor = `git config --get core.editor`.rstrip if editor.nil? || editor.empty?
82
+
83
+ # if (!editor && !terminal_is_dumb)
84
+ # editor = getenv("VISUAL");
85
+ editor = ENV['VISUAL'] if (editor.nil? || editor.empty?) && !terminal_is_dumb
86
+
87
+ # if (!editor)
88
+ # editor = getenv("EDITOR");
89
+ editor = ENV['EDITOR'] if (editor.nil? || editor.empty?)
90
+
91
+ # if (!editor && terminal_is_dumb)
92
+ # return NULL;
93
+ # if (!editor)
94
+ # editor = DEFAULT_EDITOR;
95
+ # Use vi, Git's hard-coded default
96
+ editor = 'vi' if (editor.nil? || editor.empty?) && !terminal_is_dumb
97
+
98
+ if editor && !editor.empty?
99
+ system "#{editor} '#{file}'"
100
+ $?
101
+ else
102
+ false
103
+ end
104
+ end
105
+
106
+ # Retrieves the first 99 lines of the annotation of a tag.
107
+ #
108
+ def self.get_tag_annotation(tag)
109
+ test_tag tag
110
+ `git tag --sort refname -l -n99 #{tag}`.rstrip
111
+ end
112
+
113
+ # Retrieves the author date of a tag
114
+ #
115
+ def self.get_tag_date(tag)
116
+ test_tag tag
117
+ `git log -1 --format=format:%ai #{tag}`
118
+ end
119
+
120
+ # Retrieves commit messages and filters them
121
+ # Todo: Armor this against code injection!
122
+ def self.get_filtered_messages(from_commit, to_commit, filter = nil)
123
+ if filter
124
+ `git log #{from_commit}..#{to_commit} -E --grep='#{filter}' --format=%b`
125
+ else
126
+ `git log #{from_commit}..#{to_commit} --oneline`
127
+ end
128
+ end
129
+
130
+ # Retrieves one commit message and filters it
131
+ # Todo: Armor this against code injection!
132
+ def self.get_filtered_message(commit, filter)
133
+ `git log #{commit} -E --grep='#{filter}' --format=%b`
134
+ end
135
+
136
+ @@tags = nil
137
+
138
+ # Ensures lazy loading of the tag list to enable calling code
139
+ # to change the working directory first.
140
+ def self.tags
141
+ @@tags = TagList.new unless @@tags
142
+ @@tags
143
+ end
144
+
145
+ # Tests if the given tag exists and fails if it doesn't
146
+ def self.test_tag(tag)
147
+ fail "Invalid tag: #{tag}" unless tags.list.include?(tag)
148
+ end
149
+ private_class_method :test_tag, :tags
150
+ end
151
+ end
152
+ # vim: nospell
@@ -0,0 +1,37 @@
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
+
17
+ module Git
18
+ # Represents a Git tag and its annotation.
19
+ class Tag
20
+ # Author commit date of the tag
21
+ attr_reader :date
22
+
23
+ # Tag version
24
+ attr_reader :version
25
+
26
+ # Gets change information for a specific tagged version.
27
+ #
28
+ # @param [String] tag
29
+ # Tag for which to instantiate the class.
30
+ def initialize(tag)
31
+ @version = tag
32
+ @date = Date.parse(Git.get_tag_date(tag))
33
+ end
34
+ end
35
+ end
36
+
37
+ # vim: nospell
@@ -0,0 +1,74 @@
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
+ module Git
21
+ class TagList
22
+ # Returns an array of tag names surrounded by HEAD
23
+ # at the top and the sha1 of the first commit at the
24
+ # bottom.
25
+ attr_reader :list
26
+
27
+ # Instantiates the tag list.
28
+ #
29
+ # @param [bool] include_head
30
+ # Indicates whether or not to include the most recent changes.
31
+ #
32
+ def initialize(include_head = true)
33
+ @include_head = include_head
34
+ @list = build_list
35
+ end
36
+
37
+ # Returns the most recent tag in the git repository,
38
+ # or the sha1 of the initial commit if there is no tag.
39
+ #
40
+ # @return [String]
41
+ #
42
+ def latest_tag
43
+ # Index 0 is HEAD
44
+ # Index 1 is most recent tag or first commit
45
+ @list[1]
46
+ end
47
+
48
+ private
49
+
50
+ # Returns the sha1 of the initial commit.
51
+ # In fact, this function returns all parentless commits
52
+ # of the repository. Usually there should be not more than
53
+ # one such commit.
54
+ # See http://stackoverflow.com/a/1007545/270712
55
+ #
56
+ def get_initial_commit
57
+ `git rev-list --max-parents=0 HEAD`.chomp
58
+ end
59
+
60
+ # Builds a list of Git tags and encloses it with HEAD and the
61
+ # Sha-1 of the initial commit.
62
+ #
63
+ # @return [Array]
64
+ # Array of tags, surrounded by HEAD and the Sha-1 of the initial commit.
65
+ def build_list
66
+ tags = []
67
+ tags << get_initial_commit
68
+ tags += `git tag --sort v:refname`.split("\n").map { |s| s.rstrip }
69
+ tags << "HEAD" if @include_head
70
+ tags.reverse
71
+ end
72
+ end
73
+ end
74
+ # vim: nospell
@@ -0,0 +1,37 @@
1
+ - bullet: "[F]"
2
+ filters:
3
+ - "[F]"
4
+ - "[ F ]"
5
+ - "[f]"
6
+ - "[ f ]"
7
+ header: "Features"
8
+ - bullet: "[C]"
9
+ filters:
10
+ - "[C]"
11
+ - "[ C ]"
12
+ - "[c]"
13
+ - "[ c ]"
14
+ header: "Configuration"
15
+ - bullet: "[B]"
16
+ filters:
17
+ - "[B]"
18
+ - "[ B ]"
19
+ - "[b]"
20
+ - "[ b ]"
21
+ header: "Bug Fixes"
22
+ - bullet: "[H]"
23
+ filters:
24
+ - "[H]"
25
+ - "[ H ]"
26
+ - "[h]"
27
+ - "[ h ]"
28
+ header: "Hotfixes"
29
+ - bullet: "[R]"
30
+ filters:
31
+ - "[R]"
32
+ - "[ R ]"
33
+ - "[r]"
34
+ - "[ r ]"
35
+ header: "Refactored"
36
+ - bullet: "[U]"
37
+ header: "Uncategorized"
@@ -0,0 +1,3 @@
1
+ module TagChangelog
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,25 @@
1
+ # Ensure we require the local version and not one we might have installed already
2
+ require File.join([File.dirname(__FILE__),'lib','tag_changelog','version.rb'])
3
+ spec = Gem::Specification.new do |s|
4
+ s.name = 'tag-changelog'
5
+ s.version = TagChangelog::VERSION
6
+ s.license = 'MIT'
7
+ s.author = 'Parallel6'
8
+ s.email = 'contact@parallel6.com'
9
+ s.homepage = 'http://clinical6.com'
10
+ s.platform = Gem::Platform::RUBY
11
+ s.summary = 'Tool to generate changelog based on Parallel6 specs'
12
+ s.files = `git ls-files`.split("
13
+ ")
14
+ s.require_paths << 'lib'
15
+ s.has_rdoc = true
16
+ s.extra_rdoc_files = []
17
+ s.rdoc_options << '--title' << 'tag-changelog' << '--main' << 'README.rdoc' << '-ri'
18
+ s.bindir = 'bin'
19
+ s.executables << 'tag-changelog'
20
+ s.add_development_dependency('rake')
21
+ s.add_development_dependency('rdoc')
22
+ s.add_development_dependency('aruba')
23
+ s.add_development_dependency('pry')
24
+ s.add_runtime_dependency('gli','2.17.1')
25
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ class DefaultTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def teardown
9
+ end
10
+
11
+ def test_the_truth
12
+ assert true
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ require 'test/unit'
2
+
3
+ # Add test libraries you want to use here, e.g. mocha
4
+
5
+ class Test::Unit::TestCase
6
+
7
+ # Add global extensions to the test case class here
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tag-changelog
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Parallel6
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-02-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
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'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rdoc
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: aruba
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: gli
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 2.17.1
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 2.17.1
83
+ description:
84
+ email: contact@parallel6.com
85
+ executables:
86
+ - tag-changelog
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - CHANGELOG.md
91
+ - Gemfile
92
+ - Gemfile.lock
93
+ - README.md
94
+ - Rakefile
95
+ - bin/tag-changelog
96
+ - features/changelog.feature
97
+ - features/step_definitions/changelog_steps.rb
98
+ - features/support/env.rb
99
+ - lib/tag_changelog.rb
100
+ - lib/tag_changelog/generate.rb
101
+ - lib/tag_changelog/git/git.rb
102
+ - lib/tag_changelog/git/tag.rb
103
+ - lib/tag_changelog/git/tag_list.rb
104
+ - lib/tag_changelog/templates/config.yml
105
+ - lib/tag_changelog/version.rb
106
+ - tag-changelog.gemspec
107
+ - test/default_test.rb
108
+ - test/test_helper.rb
109
+ homepage: http://clinical6.com
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options:
115
+ - "--title"
116
+ - tag-changelog
117
+ - "--main"
118
+ - README.rdoc
119
+ - "-ri"
120
+ require_paths:
121
+ - lib
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 2.5.1
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: Tool to generate changelog based on Parallel6 specs
139
+ test_files: []