github_changelog_generator 1.5.0 → 1.6.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/.rubocop_todo.yml +4 -4
- data/CHANGELOG.md +24 -0
- data/README.md +1 -1
- data/github_changelog_generator.gemspec +4 -3
- data/lib/github_changelog_generator.rb +1 -0
- data/lib/github_changelog_generator/fetcher.rb +35 -44
- data/lib/github_changelog_generator/generator/generator.rb +5 -5
- data/lib/github_changelog_generator/generator/generator_fetcher.rb +3 -3
- data/lib/github_changelog_generator/generator/generator_generation.rb +7 -6
- data/lib/github_changelog_generator/generator/generator_processor.rb +4 -4
- data/lib/github_changelog_generator/generator/generator_tags.rb +30 -11
- data/lib/github_changelog_generator/helper.rb +37 -0
- data/lib/github_changelog_generator/parser.rb +14 -5
- data/lib/github_changelog_generator/version.rb +1 -1
- data/spec/spec_helper.rb +4 -0
- data/spec/unit/fetcher_spec.rb +1 -1
- data/spec/unit/generator/generator_tags_spec.rb +95 -13
- data/spec/unit/parser_spec.rb +7 -7
- metadata +19 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3babb966b932e15a8ee0b13b12e7b877d072810
|
4
|
+
data.tar.gz: 83701aeb41ccb12157230fe5630f2adf53bb7792
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 376b9d97254be63f1a59c11fa430887d7d9ee4c71254022ecd645900c592c3ab9c48890d4f8cff83e038dc3ea5993a30c9c1cd27b811fd8942f6868879cf3bf2
|
7
|
+
data.tar.gz: a3d226901e3d1e7bd2875bc12601d9e7890ff31985eec69870c812a63ff9bf1254e2f466299950d7cb00438d4aeab7884b3542bccda4d01f557fe38373d014d0
|
data/.rubocop_todo.yml
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
-
# on 2015-
|
2
|
+
# on 2015-06-11 16:35:14 +0300 using RuboCop version 0.31.0.
|
3
3
|
# The point is for the user to remove these configuration records
|
4
4
|
# one by one as the offenses are removed from the code base.
|
5
5
|
# Note that changes in the inspected code, or installation of new
|
6
6
|
# versions of RuboCop, may require this file to be generated again.
|
7
7
|
|
8
|
-
# Offense count:
|
8
|
+
# Offense count: 13
|
9
9
|
Metrics/AbcSize:
|
10
|
-
Max:
|
10
|
+
Max: 63
|
11
11
|
|
12
12
|
# Offense count: 1
|
13
13
|
Metrics/CyclomaticComplexity:
|
@@ -21,7 +21,7 @@ Metrics/PerceivedComplexity:
|
|
21
21
|
Style/AccessorMethodName:
|
22
22
|
Enabled: false
|
23
23
|
|
24
|
-
# Offense count:
|
24
|
+
# Offense count: 10
|
25
25
|
Style/Documentation:
|
26
26
|
Enabled: false
|
27
27
|
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [Unreleased](https://github.com/skywinder/github-changelog-generator/tree/HEAD)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.5.0...HEAD)
|
6
|
+
|
7
|
+
**Fixed bugs:**
|
8
|
+
|
9
|
+
- Exclude and Include tags is broken [\#245](https://github.com/skywinder/github-changelog-generator/issues/245)
|
10
|
+
|
11
|
+
## [1.5.0](https://github.com/skywinder/github-changelog-generator/tree/1.5.0) (2015-05-26)
|
12
|
+
|
13
|
+
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.4.1...1.5.0)
|
14
|
+
|
15
|
+
**Implemented enhancements:**
|
16
|
+
|
17
|
+
- Show `Unreleased` section even when there is no tags in repo. [\#228](https://github.com/skywinder/github-changelog-generator/issues/228)
|
18
|
+
|
19
|
+
- Add option `--exclude-tags x,y,z` [\#214](https://github.com/skywinder/github-changelog-generator/issues/214)
|
20
|
+
|
21
|
+
- Generate change log between 2 specific tags [\#172](https://github.com/skywinder/github-changelog-generator/issues/172)
|
22
|
+
|
23
|
+
**Merged pull requests:**
|
24
|
+
|
25
|
+
- Big refactoring [\#243](https://github.com/skywinder/github-changelog-generator/pull/243) ([skywinder](https://github.com/skywinder))
|
26
|
+
|
3
27
|
## [1.4.1](https://github.com/skywinder/github-changelog-generator/tree/1.4.1) (2015-05-19)
|
4
28
|
|
5
29
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.4.0...1.4.1)
|
data/README.md
CHANGED
@@ -134,7 +134,7 @@ So, if you got error like this:
|
|
134
134
|
It's time to create this token or wait for 1 hour before GitHub reset the counter for your IP.
|
135
135
|
|
136
136
|
##Features and advantages of this project
|
137
|
-
- Generate canonical, neat change log file, followed by [basic change log
|
137
|
+
- Generate canonical, neat change log file, followed by [basic change log guidelines](http://keepachangelog.com/) :gem:
|
138
138
|
- Possible to generate **Unreleased** changes (closed issues that have not released yet) :dizzy:
|
139
139
|
- **GitHub Enterprise support** via command line options! :factory:
|
140
140
|
- Flexible format **customisation**:
|
@@ -23,9 +23,10 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
24
|
spec.require_paths = ["lib"]
|
25
25
|
|
26
|
-
spec.add_development_dependency "bundler", "~> 1.7"
|
27
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
-
|
29
26
|
spec.add_runtime_dependency("github_api", ["~> 0.12"])
|
30
27
|
spec.add_runtime_dependency("colorize", ["~> 0.7"])
|
28
|
+
|
29
|
+
# Development only
|
30
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
31
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
31
32
|
end
|
@@ -5,6 +5,7 @@ require "json"
|
|
5
5
|
require "colorize"
|
6
6
|
require "benchmark"
|
7
7
|
|
8
|
+
require_relative "github_changelog_generator/helper"
|
8
9
|
require_relative "github_changelog_generator/parser"
|
9
10
|
require_relative "github_changelog_generator/generator/generator"
|
10
11
|
require_relative "github_changelog_generator/version"
|
@@ -1,11 +1,10 @@
|
|
1
|
-
require "logger"
|
2
|
-
|
3
1
|
module GitHubChangelogGenerator
|
4
2
|
# A Fetcher responsible for all requests to GitHub and all basic manipulation with related data
|
5
3
|
# (such as filtering, validating, e.t.c)
|
6
4
|
#
|
7
5
|
# Example:
|
8
6
|
# fetcher = GitHubChangelogGenerator::Fetcher.new options
|
7
|
+
|
9
8
|
class Fetcher
|
10
9
|
PER_PAGE_NUMBER = 30
|
11
10
|
CHANGELOG_GITHUB_TOKEN = "CHANGELOG_GITHUB_TOKEN"
|
@@ -16,16 +15,9 @@ module GitHubChangelogGenerator
|
|
16
15
|
|
17
16
|
def initialize(options = {})
|
18
17
|
@options = options || {}
|
19
|
-
|
20
|
-
@logger = Logger.new(STDOUT)
|
21
|
-
@logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
22
|
-
"#{msg}\n"
|
23
|
-
end
|
24
|
-
|
25
18
|
@user = @options[:user]
|
26
19
|
@project = @options[:project]
|
27
20
|
@github_token = fetch_github_token
|
28
|
-
@tag_times_hash = {}
|
29
21
|
github_options = { per_page: PER_PAGE_NUMBER }
|
30
22
|
github_options[:oauth_token] = @github_token unless @github_token.nil?
|
31
23
|
github_options[:endpoint] = @options[:github_endpoint] unless @options[:github_endpoint].nil?
|
@@ -41,7 +33,7 @@ module GitHubChangelogGenerator
|
|
41
33
|
def fetch_github_token
|
42
34
|
env_var = @options[:token] ? @options[:token] : (ENV.fetch CHANGELOG_GITHUB_TOKEN, nil)
|
43
35
|
|
44
|
-
|
36
|
+
Helper.log.warn NO_TOKEN_PROVIDED.yellow unless env_var
|
45
37
|
|
46
38
|
env_var
|
47
39
|
end
|
@@ -51,27 +43,28 @@ module GitHubChangelogGenerator
|
|
51
43
|
def get_all_tags
|
52
44
|
print "Fetching tags...\r" if @options[:verbose]
|
53
45
|
|
54
|
-
|
55
|
-
|
56
|
-
check_github_response { github_fetch_tags(tags) }
|
57
|
-
|
58
|
-
tags
|
46
|
+
check_github_response { github_fetch_tags }
|
59
47
|
end
|
60
48
|
|
49
|
+
# This is wrapper with rescue block
|
50
|
+
# @return [Object] returns exactly the same, what you put in the block, but wrap it with begin-rescue block
|
61
51
|
def check_github_response
|
62
52
|
begin
|
63
53
|
value = yield
|
64
54
|
rescue Github::Error::Unauthorized => e
|
65
|
-
|
55
|
+
Helper.log.error e.body.red
|
66
56
|
abort "Error: wrong GitHub token"
|
67
57
|
rescue Github::Error::Forbidden => e
|
68
|
-
|
69
|
-
|
58
|
+
Helper.log.warn e.body.red
|
59
|
+
Helper.log.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
70
60
|
end
|
71
61
|
value
|
72
62
|
end
|
73
63
|
|
74
|
-
|
64
|
+
# Fill input array with tags
|
65
|
+
# @return [Array] array of tags in repo
|
66
|
+
def github_fetch_tags
|
67
|
+
tags = []
|
75
68
|
response = @github.repos.tags @options[:user], @options[:project]
|
76
69
|
page_i = 0
|
77
70
|
count_pages = response.count_pages
|
@@ -83,11 +76,12 @@ module GitHubChangelogGenerator
|
|
83
76
|
print_empty_line
|
84
77
|
|
85
78
|
if tags.count == 0
|
86
|
-
|
79
|
+
Helper.log.warn "Warning: Can't find any tags in repo.\
|
87
80
|
Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
88
81
|
else
|
89
|
-
|
82
|
+
Helper.log.info "Found #{tags.count} tags"
|
90
83
|
end
|
84
|
+
tags
|
91
85
|
end
|
92
86
|
|
93
87
|
# This method fetch all closed issues and separate them to pull requests and pure issues
|
@@ -112,10 +106,10 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
|
112
106
|
break if @options[:max_issues] && issues.length >= @options[:max_issues]
|
113
107
|
end
|
114
108
|
print_empty_line
|
115
|
-
|
109
|
+
Helper.log.info "Received issues: #{issues.count}"
|
116
110
|
|
117
111
|
rescue
|
118
|
-
|
112
|
+
Helper.log.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
119
113
|
end
|
120
114
|
|
121
115
|
# separate arrays of issues and pull requests:
|
@@ -140,17 +134,20 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
|
140
134
|
end
|
141
135
|
print_empty_line
|
142
136
|
rescue
|
143
|
-
|
137
|
+
Helper.log.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
144
138
|
end
|
145
139
|
|
146
|
-
|
140
|
+
Helper.log.info "Fetching merged dates: #{pull_requests.count}"
|
147
141
|
pull_requests
|
148
142
|
end
|
149
143
|
|
144
|
+
# Print specified line on the same string
|
145
|
+
# @param [String] log_string
|
150
146
|
def print_in_same_line(log_string)
|
151
147
|
print log_string + "\r"
|
152
148
|
end
|
153
149
|
|
150
|
+
# Print long line with spaces on same line to clear prev message
|
154
151
|
def print_empty_line
|
155
152
|
print_in_same_line(" ")
|
156
153
|
end
|
@@ -170,7 +167,7 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
|
170
167
|
repo: @options[:project],
|
171
168
|
issue_number: issue["number"]
|
172
169
|
rescue
|
173
|
-
|
170
|
+
Helper.log.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
174
171
|
end
|
175
172
|
issue[:events] = obj.body
|
176
173
|
print_in_same_line("Fetching events for issues and PR: #{i + 1}/#{issues.count}")
|
@@ -184,32 +181,26 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
|
184
181
|
# to clear line from prev print
|
185
182
|
print_empty_line
|
186
183
|
|
187
|
-
|
184
|
+
Helper.log.info "Fetching events for issues and PR: #{i}"
|
188
185
|
end
|
189
186
|
|
190
|
-
#
|
191
|
-
#
|
192
|
-
# @param [
|
187
|
+
# Fetch tag time from repo
|
188
|
+
#
|
189
|
+
# @param [Hash] tag
|
193
190
|
# @return [Time] time of specified tag
|
194
|
-
def
|
195
|
-
fail ChangelogGeneratorError, "tag_name is nil".red if tag_name.nil?
|
196
|
-
|
197
|
-
if @tag_times_hash[tag_name["name"]]
|
198
|
-
return @tag_times_hash[tag_name["name"]]
|
199
|
-
end
|
200
|
-
|
191
|
+
def fetch_date_of_tag(tag)
|
201
192
|
begin
|
202
|
-
|
203
|
-
|
204
|
-
|
193
|
+
commit_data = @github.git_data.commits.get @options[:user],
|
194
|
+
@options[:project],
|
195
|
+
tag["commit"]["sha"]
|
205
196
|
rescue
|
206
|
-
|
197
|
+
Helper.log.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
207
198
|
end
|
208
|
-
time_string =
|
209
|
-
|
199
|
+
time_string = commit_data["committer"]["date"]
|
200
|
+
Time.parse(time_string)
|
210
201
|
end
|
211
202
|
|
212
|
-
# Fetch commit for
|
203
|
+
# Fetch commit for specified event
|
213
204
|
# @return [Hash]
|
214
205
|
def fetch_commit(event)
|
215
206
|
@github.git_data.commits.get @options[:user], @options[:project], event[:commit_id]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative "../fetcher"
|
2
2
|
require_relative "generator_generation"
|
3
3
|
require_relative "generator_fetcher"
|
4
4
|
require_relative "generator_processor"
|
@@ -10,7 +10,7 @@ module GitHubChangelogGenerator
|
|
10
10
|
end
|
11
11
|
|
12
12
|
class Generator
|
13
|
-
attr_accessor :options, :
|
13
|
+
attr_accessor :options, :filtered_tags, :github
|
14
14
|
|
15
15
|
# A Generator responsible for all logic, related with change log generation from ready-to-parse issues
|
16
16
|
#
|
@@ -19,7 +19,7 @@ module GitHubChangelogGenerator
|
|
19
19
|
# content = generator.compound_changelog
|
20
20
|
def initialize(options = nil)
|
21
21
|
@options = options || {}
|
22
|
-
|
22
|
+
@tag_times_hash = {}
|
23
23
|
@fetcher = GitHubChangelogGenerator::Fetcher.new @options
|
24
24
|
end
|
25
25
|
|
@@ -104,12 +104,12 @@ module GitHubChangelogGenerator
|
|
104
104
|
issues.each do |dict|
|
105
105
|
added = false
|
106
106
|
dict.labels.each do |label|
|
107
|
-
if label.name
|
107
|
+
if @options[:bug_labels].include? label.name
|
108
108
|
bugs_a.push dict
|
109
109
|
added = true
|
110
110
|
next
|
111
111
|
end
|
112
|
-
if label.name
|
112
|
+
if @options[:enhancement_labels].include? label.name
|
113
113
|
enhancement_a.push dict
|
114
114
|
added = true
|
115
115
|
next
|
@@ -17,11 +17,11 @@ module GitHubChangelogGenerator
|
|
17
17
|
# Async fetching tags:
|
18
18
|
threads = []
|
19
19
|
i = 0
|
20
|
-
all = @
|
21
|
-
@
|
20
|
+
all = @filtered_tags.count
|
21
|
+
@filtered_tags.each do |tag|
|
22
22
|
print " \r"
|
23
23
|
threads << Thread.new do
|
24
|
-
|
24
|
+
get_time_of_tag(tag)
|
25
25
|
print "Fetching tags dates: #{i + 1}/#{all}\r" if @options[:verbose]
|
26
26
|
i += 1
|
27
27
|
end
|
@@ -5,6 +5,7 @@ module GitHubChangelogGenerator
|
|
5
5
|
# @return [String] Generated change log file
|
6
6
|
def compound_changelog
|
7
7
|
fetch_and_filter_tags
|
8
|
+
sort_tags_by_date(@filtered_tags)
|
8
9
|
fetch_issues_and_pr
|
9
10
|
|
10
11
|
log = "# Change Log\n\n"
|
@@ -24,7 +25,7 @@ module GitHubChangelogGenerator
|
|
24
25
|
tag1 = @options[:tag1]
|
25
26
|
tag2 = @options[:tag2]
|
26
27
|
tags_strings = []
|
27
|
-
|
28
|
+
filtered_tags.each { |x| tags_strings.push(x["name"]) }
|
28
29
|
|
29
30
|
if tags_strings.include?(tag1)
|
30
31
|
if tags_strings.include?(tag2)
|
@@ -128,11 +129,11 @@ module GitHubChangelogGenerator
|
|
128
129
|
|
129
130
|
log = generate_unreleased_section
|
130
131
|
|
131
|
-
(1...
|
132
|
-
log += generate_log_between_tags(
|
132
|
+
(1...filtered_tags.size).each do |index|
|
133
|
+
log += generate_log_between_tags(filtered_tags[index], filtered_tags[index - 1])
|
133
134
|
end
|
134
|
-
if @
|
135
|
-
log += generate_log_between_tags(nil,
|
135
|
+
if @filtered_tags.count != 0
|
136
|
+
log += generate_log_between_tags(nil, filtered_tags.last)
|
136
137
|
end
|
137
138
|
|
138
139
|
log
|
@@ -141,7 +142,7 @@ module GitHubChangelogGenerator
|
|
141
142
|
def generate_unreleased_section
|
142
143
|
log = ""
|
143
144
|
if @options[:unreleased]
|
144
|
-
unreleased_log = generate_log_between_tags(
|
145
|
+
unreleased_log = generate_log_between_tags(filtered_tags[0], nil)
|
145
146
|
log += unreleased_log if unreleased_log
|
146
147
|
end
|
147
148
|
log
|
@@ -36,7 +36,7 @@ module GitHubChangelogGenerator
|
|
36
36
|
false
|
37
37
|
else
|
38
38
|
# check, that this milestone in tag list:
|
39
|
-
milestone_is_tag = @
|
39
|
+
milestone_is_tag = @filtered_tags.find do |tag|
|
40
40
|
tag.name == issue.milestone.title
|
41
41
|
end
|
42
42
|
|
@@ -57,7 +57,7 @@ module GitHubChangelogGenerator
|
|
57
57
|
true
|
58
58
|
else
|
59
59
|
# check, that this milestone in tag list:
|
60
|
-
@
|
60
|
+
@filtered_tags.find { |tag| tag.name == issue.milestone.title }.nil?
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -72,8 +72,8 @@ module GitHubChangelogGenerator
|
|
72
72
|
# in case if not tags specified - return unchanged array
|
73
73
|
return array if older_tag.nil? && newer_tag.nil?
|
74
74
|
|
75
|
-
newer_tag_time = newer_tag &&
|
76
|
-
older_tag_time = older_tag &&
|
75
|
+
newer_tag_time = newer_tag && get_time_of_tag(newer_tag)
|
76
|
+
older_tag_time = older_tag && get_time_of_tag(older_tag)
|
77
77
|
|
78
78
|
array.select do |req|
|
79
79
|
if req[hash_key]
|
@@ -2,15 +2,34 @@ module GitHubChangelogGenerator
|
|
2
2
|
class Generator
|
3
3
|
# fetch, filter tags, fetch dates and sort them in time order
|
4
4
|
def fetch_and_filter_tags
|
5
|
-
@
|
5
|
+
@filtered_tags = get_filtered_tags(@fetcher.get_all_tags)
|
6
6
|
fetch_tags_dates
|
7
|
-
sort_tags_by_date
|
8
7
|
end
|
9
8
|
|
10
9
|
# Sort all tags by date
|
11
|
-
def sort_tags_by_date
|
10
|
+
def sort_tags_by_date(tags)
|
12
11
|
puts "Sorting tags..." if @options[:verbose]
|
13
|
-
|
12
|
+
tags.sort_by! do |x|
|
13
|
+
get_time_of_tag(x)
|
14
|
+
end.reverse!
|
15
|
+
end
|
16
|
+
|
17
|
+
# Try to find tag date in local hash.
|
18
|
+
# Otherwise fFetch tag time and put it to local hash file.
|
19
|
+
# @param [Hash] tag_name name of the tag
|
20
|
+
# @return [Time] time of specified tag
|
21
|
+
def get_time_of_tag(tag_name)
|
22
|
+
fail ChangelogGeneratorError, "tag_name is nil".red if tag_name.nil?
|
23
|
+
|
24
|
+
name_of_tag = tag_name["name"]
|
25
|
+
time_for_name = @tag_times_hash[name_of_tag]
|
26
|
+
if !time_for_name.nil?
|
27
|
+
time_for_name
|
28
|
+
else
|
29
|
+
time_string = @fetcher.fetch_date_of_tag tag_name
|
30
|
+
@tag_times_hash[name_of_tag] = time_string
|
31
|
+
time_string
|
32
|
+
end
|
14
33
|
end
|
15
34
|
|
16
35
|
# Detect link, name and time for specified tag.
|
@@ -19,7 +38,7 @@ module GitHubChangelogGenerator
|
|
19
38
|
# @return [Array] link, name and time of the tag
|
20
39
|
def detect_link_tag_time(newer_tag)
|
21
40
|
# if tag is nil - set current time
|
22
|
-
newer_tag_time = newer_tag.nil? ? Time.new :
|
41
|
+
newer_tag_time = newer_tag.nil? ? Time.new : get_time_of_tag(newer_tag)
|
23
42
|
|
24
43
|
# if it's future release tag - set this value
|
25
44
|
if newer_tag.nil? && @options[:future_release]
|
@@ -45,11 +64,11 @@ module GitHubChangelogGenerator
|
|
45
64
|
filtered_tags = all_tags
|
46
65
|
if @options[:between_tags]
|
47
66
|
@options[:between_tags].each do |tag|
|
48
|
-
unless all_tags.include? tag
|
49
|
-
|
67
|
+
unless all_tags.map(&:name).include? tag
|
68
|
+
Helper.log.warn "Warning: can't find tag #{tag}, specified with --between-tags option."
|
50
69
|
end
|
51
70
|
end
|
52
|
-
filtered_tags = all_tags.select { |tag| @options[:between_tags].include? tag }
|
71
|
+
filtered_tags = all_tags.select { |tag| @options[:between_tags].include? tag.name }
|
53
72
|
end
|
54
73
|
filtered_tags
|
55
74
|
end
|
@@ -58,11 +77,11 @@ module GitHubChangelogGenerator
|
|
58
77
|
filtered_tags = all_tags
|
59
78
|
if @options[:exclude_tags]
|
60
79
|
@options[:exclude_tags].each do |tag|
|
61
|
-
unless all_tags.include? tag
|
62
|
-
|
80
|
+
unless all_tags.map(&:name).include? tag
|
81
|
+
Helper.log.warn "Warning: can't find tag #{tag}, specified with --exclude-tags option."
|
63
82
|
end
|
64
83
|
end
|
65
|
-
filtered_tags = all_tags.reject { |tag| @options[:exclude_tags].include? tag }
|
84
|
+
filtered_tags = all_tags.reject { |tag| @options[:exclude_tags].include? tag.name }
|
66
85
|
end
|
67
86
|
filtered_tags
|
68
87
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "logger"
|
2
|
+
module GitHubChangelogGenerator
|
3
|
+
module Helper
|
4
|
+
# @return true if the currently running program is a unit test
|
5
|
+
def self.test?
|
6
|
+
defined?SpecHelper
|
7
|
+
end
|
8
|
+
|
9
|
+
if test?
|
10
|
+
@log ||= Logger.new(nil) # don't show any logs when running tests
|
11
|
+
else
|
12
|
+
@log ||= Logger.new(STDOUT)
|
13
|
+
end
|
14
|
+
@log.formatter = proc do |severity, _datetime, _progname, msg|
|
15
|
+
string = "#{msg}\n"
|
16
|
+
|
17
|
+
if severity == "DEBUG"
|
18
|
+
string = string.magenta
|
19
|
+
elsif severity == "INFO"
|
20
|
+
string = string.white
|
21
|
+
elsif severity == "WARN"
|
22
|
+
string = string.yellow
|
23
|
+
elsif severity == "ERROR"
|
24
|
+
string = string.red
|
25
|
+
elsif severity == "FATAL"
|
26
|
+
string = string.red.bold
|
27
|
+
end
|
28
|
+
|
29
|
+
string
|
30
|
+
end
|
31
|
+
|
32
|
+
# Logging happens using this method
|
33
|
+
class << self
|
34
|
+
attr_reader :log
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
require "optparse"
|
3
3
|
require "pp"
|
4
4
|
require_relative "version"
|
5
|
-
|
5
|
+
require_relative "helper"
|
6
6
|
module GitHubChangelogGenerator
|
7
7
|
class Parser
|
8
8
|
# parse options with optparse
|
@@ -13,7 +13,9 @@ module GitHubChangelogGenerator
|
|
13
13
|
|
14
14
|
parser.parse!
|
15
15
|
|
16
|
-
|
16
|
+
if options[:user].nil? || options[:project].nil?
|
17
|
+
detect_user_and_project(options)
|
18
|
+
end
|
17
19
|
|
18
20
|
if !options[:user] || !options[:project]
|
19
21
|
puts parser.banner
|
@@ -21,7 +23,7 @@ module GitHubChangelogGenerator
|
|
21
23
|
end
|
22
24
|
|
23
25
|
if options[:verbose]
|
24
|
-
|
26
|
+
Helper.log.info "Performing task with options:"
|
25
27
|
pp options
|
26
28
|
puts ""
|
27
29
|
end
|
@@ -84,6 +86,12 @@ module GitHubChangelogGenerator
|
|
84
86
|
opts.on("--exclude-labels x,y,z", Array, 'Issues with the specified labels will be always excluded from changelog. Default is \'duplicate,question,invalid,wontfix\'') do |list|
|
85
87
|
options[:exclude_labels] = list
|
86
88
|
end
|
89
|
+
opts.on("--bug-labels x,y,z", Array, 'Issues with the specified labels will be always added to "Fixed bugs" section. Default is \'bug,Bug\'') do |list|
|
90
|
+
options[:bug_labels] = list
|
91
|
+
end
|
92
|
+
opts.on("--enhancement-labels x,y,z", Array, 'Issues with the specified labels will be always added to "Implemented enhancements" section. Default is \'enhancement,Enhancement\'') do |list|
|
93
|
+
options[:enhancement_labels] = list
|
94
|
+
end
|
87
95
|
opts.on("--between-tags x,y,z", Array, "Change log will be filled only between specified tags") do |list|
|
88
96
|
options[:between_tags] = list
|
89
97
|
end
|
@@ -136,8 +144,9 @@ module GitHubChangelogGenerator
|
|
136
144
|
unreleased: true,
|
137
145
|
unreleased_label: "Unreleased",
|
138
146
|
compare_link: true,
|
139
|
-
|
140
|
-
|
147
|
+
enhancement_labels: %w(enhancement Enhancement),
|
148
|
+
bug_labels: %w(bug Bug),
|
149
|
+
exclude_labels: %w(duplicate question invalid wontfix Duplicate Question Invalid Wontfix),
|
141
150
|
max_issues: nil,
|
142
151
|
simple_list: false,
|
143
152
|
verbose: true,
|
data/spec/spec_helper.rb
CHANGED
@@ -19,6 +19,10 @@ require "codeclimate-test-reporter"
|
|
19
19
|
require "simplecov"
|
20
20
|
require "coveralls"
|
21
21
|
|
22
|
+
# This module is only used to check the environment is currently a testing env
|
23
|
+
module SpecHelper
|
24
|
+
end
|
25
|
+
|
22
26
|
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
23
27
|
Coveralls::SimpleCov::Formatter,
|
24
28
|
SimpleCov::Formatter::HTMLFormatter,
|
data/spec/unit/fetcher_spec.rb
CHANGED
@@ -52,7 +52,7 @@ describe GitHubChangelogGenerator::Fetcher do
|
|
52
52
|
@fetcher = GitHubChangelogGenerator::Fetcher.new(options)
|
53
53
|
end
|
54
54
|
it "should raise Unauthorized error" do
|
55
|
-
expect { @fetcher.github_fetch_tags
|
55
|
+
expect { @fetcher.github_fetch_tags }.to raise_error Github::Error::Unauthorized
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -1,3 +1,18 @@
|
|
1
|
+
def tag_mash_with_name(tag)
|
2
|
+
mash_tag = Hashie::Mash.new
|
3
|
+
mash_tag.name = tag
|
4
|
+
mash_tag
|
5
|
+
end
|
6
|
+
|
7
|
+
def tags_mash_from_strings(tags_strings)
|
8
|
+
mash_array = []
|
9
|
+
tags_strings.each do |tag|
|
10
|
+
mash_tag = tag_mash_with_name(tag)
|
11
|
+
mash_array << mash_tag
|
12
|
+
end
|
13
|
+
mash_array
|
14
|
+
end
|
15
|
+
|
1
16
|
describe GitHubChangelogGenerator::Generator do
|
2
17
|
describe "#filter_between_tags" do
|
3
18
|
context "when between_tags nil" do
|
@@ -6,20 +21,20 @@ describe GitHubChangelogGenerator::Generator do
|
|
6
21
|
end
|
7
22
|
|
8
23
|
subject do
|
9
|
-
@generator.get_filtered_tags(%w(1 2 3))
|
24
|
+
@generator.get_filtered_tags(tags_mash_from_strings(%w(1 2 3)))
|
10
25
|
end
|
11
26
|
it { is_expected.to be_a(Array) }
|
12
|
-
it { is_expected.to match_array(%w(1 2 3)) }
|
27
|
+
it { is_expected.to match_array(tags_mash_from_strings(%w(1 2 3))) }
|
13
28
|
end
|
14
29
|
context "when between_tags same as input array" do
|
15
30
|
before do
|
16
31
|
@generator = GitHubChangelogGenerator::Generator.new(between_tags: %w(1 2 3))
|
17
32
|
end
|
18
33
|
subject do
|
19
|
-
@generator.get_filtered_tags(%w(1 2 3))
|
34
|
+
@generator.get_filtered_tags(tags_mash_from_strings(%w(1 2 3)))
|
20
35
|
end
|
21
36
|
it { is_expected.to be_a(Array) }
|
22
|
-
it { is_expected.to match_array(%w(1 2 3)) }
|
37
|
+
it { is_expected.to match_array(tags_mash_from_strings(%w(1 2 3))) }
|
23
38
|
end
|
24
39
|
|
25
40
|
context "when between_tags filled with correct values" do
|
@@ -27,10 +42,10 @@ describe GitHubChangelogGenerator::Generator do
|
|
27
42
|
@generator = GitHubChangelogGenerator::Generator.new(between_tags: %w(1 2))
|
28
43
|
end
|
29
44
|
subject do
|
30
|
-
@generator.get_filtered_tags(%w(1 2 3))
|
45
|
+
@generator.get_filtered_tags(tags_mash_from_strings(%w(1 2 3)))
|
31
46
|
end
|
32
47
|
it { is_expected.to be_a(Array) }
|
33
|
-
it { is_expected.to match_array(%w(1 2)) }
|
48
|
+
it { is_expected.to match_array(tags_mash_from_strings(%w(1 2))) }
|
34
49
|
end
|
35
50
|
|
36
51
|
context "when between_tags filled with invalid values" do
|
@@ -39,31 +54,98 @@ describe GitHubChangelogGenerator::Generator do
|
|
39
54
|
end
|
40
55
|
|
41
56
|
subject do
|
42
|
-
@generator.get_filtered_tags(%w(1 2 3))
|
57
|
+
@generator.get_filtered_tags(tags_mash_from_strings(%w(1 2 3)))
|
43
58
|
end
|
44
59
|
it { is_expected.to be_a(Array) }
|
45
|
-
it { is_expected.to match_array(%w(1)) }
|
60
|
+
it { is_expected.to match_array(tags_mash_from_strings(%w(1))) }
|
46
61
|
end
|
47
62
|
end
|
48
63
|
|
49
64
|
describe "#get_filtered_tags" do
|
50
|
-
subject
|
51
|
-
|
65
|
+
subject do
|
66
|
+
generator.get_filtered_tags(tags_mash_from_strings(%w(1 2 3 4 5)))
|
67
|
+
end
|
52
68
|
|
53
69
|
context "with excluded and between tags" do
|
54
70
|
let(:generator) { GitHubChangelogGenerator::Generator.new(between_tags: %w(1 2 3), exclude_tags: %w(2)) }
|
55
71
|
it { is_expected.to be_a Array }
|
56
|
-
it { is_expected.to match_array(%w(1 3)) }
|
72
|
+
it { is_expected.to match_array(tags_mash_from_strings(%w(1 3))) }
|
57
73
|
end
|
58
74
|
end
|
59
75
|
|
60
76
|
describe "#filter_excluded_tags" do
|
61
|
-
subject { generator.filter_excluded_tags(%w(1 2 3)) }
|
77
|
+
subject { generator.filter_excluded_tags(tags_mash_from_strings(%w(1 2 3))) }
|
62
78
|
|
63
79
|
context "with valid excluded tags" do
|
64
80
|
let(:generator) { GitHubChangelogGenerator::Generator.new(exclude_tags: %w(3)) }
|
65
81
|
it { is_expected.to be_a Array }
|
66
|
-
it { is_expected.to match_array(%w(1 2)) }
|
82
|
+
it { is_expected.to match_array(tags_mash_from_strings(%w(1 2))) }
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with invalid excluded tags" do
|
86
|
+
let(:generator) { GitHubChangelogGenerator::Generator.new(exclude_tags: %w(invalid tags)) }
|
87
|
+
it { is_expected.to be_a Array }
|
88
|
+
it { is_expected.to match_array(tags_mash_from_strings(%w(1 2 3))) }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#get_time_of_tag" do
|
93
|
+
current_time = Time.now
|
94
|
+
before(:all) { @generator = GitHubChangelogGenerator::Generator.new }
|
95
|
+
context "run with nil parameter" do
|
96
|
+
it "should raise ChangelogGeneratorError" do
|
97
|
+
expect { @generator.get_time_of_tag nil }.to raise_error(GitHubChangelogGenerator::ChangelogGeneratorError)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
context "fetch already filled tag" do
|
101
|
+
before { @generator.instance_variable_set :@tag_times_hash, "valid_tag" => current_time }
|
102
|
+
subject { @generator.get_time_of_tag tag_mash_with_name("valid_tag") }
|
103
|
+
it { is_expected.to be_a_kind_of(Time) }
|
104
|
+
it { is_expected.to eq(current_time) }
|
105
|
+
end
|
106
|
+
context "fetch not filled tag" do
|
107
|
+
before do
|
108
|
+
mock = double("fake fetcher")
|
109
|
+
allow(mock).to receive_messages(fetch_date_of_tag: current_time)
|
110
|
+
@generator.instance_variable_set :@fetcher, mock
|
111
|
+
end
|
112
|
+
subject do
|
113
|
+
of_tag = @generator.get_time_of_tag tag_mash_with_name("valid_tag")
|
114
|
+
of_tag
|
115
|
+
end
|
116
|
+
it { is_expected.to be_a_kind_of(Time) }
|
117
|
+
it { is_expected.to eq(current_time) }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "#sort_tags_by_date" do
|
122
|
+
time1 = Time.now
|
123
|
+
time2 = Time.now
|
124
|
+
time3 = Time.now
|
125
|
+
before(:all) do
|
126
|
+
@generator = GitHubChangelogGenerator::Generator.new
|
127
|
+
end
|
128
|
+
context "sort unsorted tags" do
|
129
|
+
tags = tags_mash_from_strings %w(valid_tag1 valid_tag2 valid_tag3)
|
130
|
+
before do
|
131
|
+
@generator.instance_variable_set :@tag_times_hash, "valid_tag1" => time1, "valid_tag2" => time2, "valid_tag3" => time3
|
132
|
+
end
|
133
|
+
subject do
|
134
|
+
@generator.sort_tags_by_date tags
|
135
|
+
end
|
136
|
+
it { is_expected.to be_a_kind_of(Array) }
|
137
|
+
it { is_expected.to match_array(tags.reverse!) }
|
138
|
+
end
|
139
|
+
context "sort sorted tags" do
|
140
|
+
tags = tags_mash_from_strings %w(valid_tag3 valid_tag2 valid_tag1)
|
141
|
+
before do
|
142
|
+
@generator.instance_variable_set :@tag_times_hash, "valid_tag1" => time1, "valid_tag2" => time2, "valid_tag3" => time3
|
143
|
+
end
|
144
|
+
subject do
|
145
|
+
@generator.sort_tags_by_date tags
|
146
|
+
end
|
147
|
+
it { is_expected.to be_a_kind_of(Array) }
|
148
|
+
it { is_expected.to match_array(tags) }
|
67
149
|
end
|
68
150
|
end
|
69
151
|
end
|
data/spec/unit/parser_spec.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
describe GitHubChangelogGenerator::Parser do
|
2
2
|
describe ".user_project_from_remote" do
|
3
|
-
context "when remote is 1" do
|
3
|
+
context "when remote is type 1" do
|
4
4
|
subject { GitHubChangelogGenerator::Parser.user_project_from_remote("origin https://github.com/skywinder/ActionSheetPicker-3.0 (fetch)") }
|
5
5
|
it { is_expected.to be_a(Array) }
|
6
6
|
it { is_expected.to match_array(["skywinder", "ActionSheetPicker-3.0"]) }
|
7
7
|
end
|
8
|
-
context "when remote is 2" do
|
8
|
+
context "when remote is type 2" do
|
9
9
|
subject { GitHubChangelogGenerator::Parser.user_project_from_remote("https://github.com/skywinder/ActionSheetPicker-3.0") }
|
10
10
|
it { is_expected.to be_a(Array) }
|
11
11
|
it { is_expected.to match_array(["skywinder", "ActionSheetPicker-3.0"]) }
|
12
12
|
end
|
13
|
-
context "when remote is 3" do
|
13
|
+
context "when remote is type 3" do
|
14
14
|
subject { GitHubChangelogGenerator::Parser.user_project_from_remote("https://github.com/skywinder/ActionSheetPicker-3.0") }
|
15
15
|
it { is_expected.to be_a(Array) }
|
16
16
|
it { is_expected.to match_array(["skywinder", "ActionSheetPicker-3.0"]) }
|
17
17
|
end
|
18
|
-
context "when remote is 4" do
|
18
|
+
context "when remote is type 4" do
|
19
19
|
subject { GitHubChangelogGenerator::Parser.user_project_from_remote("origin git@github.com:skywinder/ActionSheetPicker-3.0.git (fetch)") }
|
20
20
|
it { is_expected.to be_a(Array) }
|
21
21
|
it { is_expected.to match_array(["skywinder", "ActionSheetPicker-3.0"]) }
|
@@ -27,9 +27,9 @@ describe GitHubChangelogGenerator::Parser do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
describe ".user_project_from_option" do
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
context "when option is invalid" do
|
31
|
+
it("should exit") { expect { GitHubChangelogGenerator::Parser.user_project_from_option("blah", nil) }.to raise_error(SystemExit) }
|
32
|
+
end
|
33
33
|
|
34
34
|
context "when option is valid" do
|
35
35
|
subject { GitHubChangelogGenerator::Parser.user_project_from_option("skywinder/ActionSheetPicker-3.0", nil) }
|
metadata
CHANGED
@@ -1,71 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github_changelog_generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Petr Korolev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: github_api
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
type: :
|
19
|
+
version: '0.12'
|
20
|
+
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0.12'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: colorize
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
34
|
-
type: :
|
33
|
+
version: '0.7'
|
34
|
+
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0.7'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
-
type: :
|
47
|
+
version: '1.7'
|
48
|
+
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '1.7'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0
|
62
|
-
type: :
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0
|
68
|
+
version: '10.0'
|
69
69
|
description: Changelog generation has never been so easy. Fully automate changelog
|
70
70
|
generation - this gem generate change log file based on tags, issues and merged
|
71
71
|
pull requests from Github issue tracker.
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- lib/github_changelog_generator/generator/generator_generation.rb
|
100
100
|
- lib/github_changelog_generator/generator/generator_processor.rb
|
101
101
|
- lib/github_changelog_generator/generator/generator_tags.rb
|
102
|
+
- lib/github_changelog_generator/helper.rb
|
102
103
|
- lib/github_changelog_generator/parser.rb
|
103
104
|
- lib/github_changelog_generator/reader.rb
|
104
105
|
- lib/github_changelog_generator/version.rb
|