tag-changelog 0.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: 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: []