github_changelog_generator 1.14.3 → 1.15.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -22
- data/Rakefile +6 -26
- data/bin/ghclgen +1 -0
- data/lib/github_changelog_generator.rb +10 -13
- data/lib/github_changelog_generator/generator/generator.rb +19 -8
- data/lib/github_changelog_generator/generator/generator_fetcher.rb +2 -1
- data/lib/github_changelog_generator/generator/generator_generation.rb +11 -8
- data/lib/github_changelog_generator/generator/generator_processor.rb +7 -8
- data/lib/github_changelog_generator/generator/generator_tags.rb +41 -41
- data/lib/github_changelog_generator/helper.rb +1 -0
- data/lib/github_changelog_generator/octo_fetcher.rb +25 -4
- data/lib/github_changelog_generator/options.rb +50 -57
- data/lib/github_changelog_generator/parser.rb +16 -15
- data/lib/github_changelog_generator/parser_file.rb +4 -3
- data/lib/github_changelog_generator/reader.rb +1 -0
- data/lib/github_changelog_generator/ssl_certs/cacert.pem +4043 -0
- data/lib/github_changelog_generator/task.rb +3 -2
- data/lib/github_changelog_generator/version.rb +2 -1
- data/man/git-generate-changelog.1 +3 -3
- data/man/git-generate-changelog.1.html +3 -7
- data/man/git-generate-changelog.html +0 -4
- data/man/git-generate-changelog.md +6 -6
- data/spec/spec_helper.rb +2 -3
- data/spec/unit/generator/generator_generation_spec.rb +17 -0
- data/spec/unit/generator/generator_processor_spec.rb +64 -13
- data/spec/unit/generator/generator_tags_spec.rb +123 -65
- data/spec/unit/octo_fetcher_spec.rb +17 -2
- data/spec/unit/options_spec.rb +1 -0
- data/spec/unit/parse_file_spec.rb +6 -6
- data/spec/unit/parser_spec.rb +1 -0
- data/spec/unit/reader_spec.rb +1 -0
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits_before/when_API_is_valid/returns_commits.json +1 -0
- metadata +14 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90e44c8d99a9213765a5d46605dd584956f79ca0
|
4
|
+
data.tar.gz: e42720ae60fc9c8096c41cb51456e0aacdcc8b69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fafd2adab89a40c20fc1975da3a569f7a559c377d564c8b79268d6630472daf54f00ed52389c3fc351c93f645106305454943bdbdde740d51b23eb508dec57fb
|
7
|
+
data.tar.gz: 6143d6c610624b8ac836292698d01e6adb941c2fa21399ab85e7831982587d7b329a802c7fba0c51b986b85b58860850b1c2cb9034ffac7bdcc2329c0f0f01f6
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[![Gem Version](https://badge.fury.io/rb/github_changelog_generator.svg)](http://badge.fury.io/rb/github_changelog_generator)
|
2
2
|
[![Dependency Status](https://gemnasium.com/skywinder/github-changelog-generator.svg)](https://gemnasium.com/skywinder/github-changelog-generator)
|
3
3
|
[![Build Status](https://travis-ci.org/skywinder/github-changelog-generator.svg?branch=master)](https://travis-ci.org/skywinder/github-changelog-generator)
|
4
|
+
[![Build status](https://ci.appveyor.com/api/projects/status/xdfnfmdjfo0upm7m?svg=true)](https://ci.appveyor.com/project/olleolleolle/github-changelog-generator)
|
4
5
|
[![Inline docs](http://inch-ci.org/github/skywinder/github-changelog-generator.svg)](http://inch-ci.org/github/skywinder/github-changelog-generator)
|
5
6
|
[![Code Climate](https://codeclimate.com/github/skywinder/github-changelog-generator/badges/gpa.svg)](https://codeclimate.com/github/skywinder/github-changelog-generator)
|
6
7
|
[![Test Coverage](https://codeclimate.com/github/skywinder/github-changelog-generator/badges/coverage.svg)](https://codeclimate.com/github/skywinder/github-changelog-generator)
|
@@ -24,20 +25,20 @@ GitHub Changelog Generator ![GitHub Logo](../master/images/logo.jpg)
|
|
24
25
|
|
25
26
|
### Changelog generation has never been so easy
|
26
27
|
|
27
|
-
**Fully
|
28
|
+
**Fully automated changelog generation** - This gem generates a change log file based on **tags**, **issues** and merged **pull requests** (and splits them into separate lists according to labels) from :octocat: GitHub Issue Tracker.
|
28
29
|
|
29
|
-
Since
|
30
|
+
Since you don't have to fill your `CHANGELOG.md` manually now: just run the script, relax and take a cup of :coffee: before your next release! :tada:
|
30
31
|
|
31
|
-
|
32
|
+
### *What’s the point of a change log?*
|
32
33
|
To make it easier for users and contributors to see precisely what notable changes have been made between each release (or version) of the project.
|
33
34
|
### *Why should I care?*
|
34
35
|
Because software tools are for people. If you don’t care, why are you contributing to open source? Surely, there must be a kernel (ha!) of care somewhere in that lovely little brain of yours.
|
35
36
|
|
36
|
-
|
37
|
+
:arrow_right: *[http://keepachangelog.com](http://keepachangelog.com)*
|
37
38
|
|
38
39
|
## Installation
|
39
40
|
|
40
|
-
|
41
|
+
gem install github_changelog_generator
|
41
42
|
|
42
43
|
See also Troubleshooting.
|
43
44
|
|
@@ -46,7 +47,7 @@ See also Troubleshooting.
|
|
46
47
|
- Look at **[CHANGELOG.md](https://github.com/skywinder/Github-Changelog-Generator/blob/master/CHANGELOG.md)** for this project
|
47
48
|
- [ActionSheetPicker-3.0/CHANGELOG.md](https://github.com/skywinder/ActionSheetPicker-3.0/blob/master/CHANGELOG.md) was generated by command:
|
48
49
|
|
49
|
-
|
50
|
+
github_changelog_generator -u skywinder -p ActionSheetPicker-3.0
|
50
51
|
|
51
52
|
- In general, it looks like this:
|
52
53
|
|
@@ -74,16 +75,16 @@ See also Troubleshooting.
|
|
74
75
|
|
75
76
|
- If your **`git remote`** `origin` refers to your GitHub repo, just go to your project folder and run:
|
76
77
|
|
77
|
-
|
78
|
+
github_changelog_generator
|
78
79
|
|
79
80
|
- Or, run this from anywhere:
|
80
|
-
|
81
|
-
|
81
|
+
`github_changelog_generator -u github_username -p github_project`
|
82
|
+
`github_changelog_generator github_username/github_project`
|
82
83
|
|
83
84
|
- If you are running it against a repository on a Github Enterprise install, you must specify *both* `--github-site` and `--github-api` command line options:
|
84
85
|
|
85
|
-
|
86
|
-
|
86
|
+
github_changelog_generator --github-site="https://github.yoursite.com" \
|
87
|
+
--github-api="https://github.yoursite.com/api/v3/"
|
87
88
|
|
88
89
|
This generates a changelog to the `CHANGELOG.md` file, with pretty markdown formatting.
|
89
90
|
|
@@ -104,7 +105,7 @@ since-tag=1.0.0
|
|
104
105
|
|
105
106
|
### GitHub token
|
106
107
|
|
107
|
-
GitHub only allows
|
108
|
+
GitHub only allows 50 unauthenticated requests per hour.
|
108
109
|
Therefore, it's recommended to run this script with authentication by using a **token**.
|
109
110
|
|
110
111
|
Here's how:
|
@@ -116,10 +117,14 @@ Here's how:
|
|
116
117
|
|
117
118
|
You can set an environment variable by running the following command at the prompt, or by adding it to your shell profile (e.g., `~/.bash_profile` or `~/.zshrc`):
|
118
119
|
|
119
|
-
|
120
|
+
export CHANGELOG_GITHUB_TOKEN="«your-40-digit-github-token»"
|
120
121
|
|
121
|
-
So, if you
|
122
|
-
|
122
|
+
So, if you get a message like this:
|
123
|
+
|
124
|
+
``` markdown
|
125
|
+
API rate limit exceeded for github_username.
|
126
|
+
See: https://developer.github.com/v3/#rate-limiting
|
127
|
+
```
|
123
128
|
|
124
129
|
It's time to create this token! (Or, wait an hour for GitHub to reset your unauthenticated request limit.)
|
125
130
|
|
@@ -135,7 +140,7 @@ If you have a `HISTORY.md` file in your project, it will automatically be picked
|
|
135
140
|
|
136
141
|
### Rake task
|
137
142
|
|
138
|
-
You love `rake`? We do, too! So, we've made it even easier for you:
|
143
|
+
You love `rake`? We do, too! So, we've made it even easier for you:
|
139
144
|
we've provided a `rake` task library for your changelog generation.
|
140
145
|
|
141
146
|
Just put something like this in your `Rakefile`:
|
@@ -173,7 +178,7 @@ You can look for params names from the [parser source code (#setup_parser)](http
|
|
173
178
|
(*See `github_changelog_generator --help` for details)*
|
174
179
|
|
175
180
|
|
176
|
-
###Alternatives
|
181
|
+
### Alternatives
|
177
182
|
Here is a [wikipage list of alternatives](https://github.com/skywinder/Github-Changelog-Generator/wiki/Alternatives) that I found. But none satisfied my requirements.
|
178
183
|
|
179
184
|
*If you know other projects, feel free to edit this Wiki page!*
|
@@ -208,14 +213,14 @@ An auto-generated changelog really helps, even if you manually fill in the relea
|
|
208
213
|
|
209
214
|
For example:
|
210
215
|
|
211
|
-
When
|
212
|
-
|
216
|
+
When you find a closed bug, it is very useful to know which release fixed it.
|
217
|
+
So that you can easily find the issue by \# in `CHANGELOG.md`.
|
213
218
|
|
214
219
|
- it's not quite as easy to find this in handwritten releases notes
|
215
220
|
- a generated file saves you the trouble of remembering everything;
|
216
221
|
sometimes people forget to add things to a handwritten file
|
217
222
|
|
218
|
-
Ultimately, I think GitHub Releases
|
223
|
+
Ultimately, I think GitHub Releases are ideal for end-users.
|
219
224
|
Meanwhile, `CHANGELOG.md` lives right in the repository, with its detailed list of changes, which is handy for developers.
|
220
225
|
Finally, there's nothing wrong with using GitHub Releases alongside `CHANGELOG.md` in this combination.
|
221
226
|
|
@@ -256,14 +261,14 @@ can't get the latest version of Ruby installed.
|
|
256
261
|
## Contributing
|
257
262
|
|
258
263
|
1. Create an issue and describe your idea
|
259
|
-
2. [Fork it]
|
264
|
+
2. [Fork it](https://github.com/skywinder/github-changelog-generator/fork)
|
260
265
|
3. Create your feature branch (`git checkout -b my-new-feature`)
|
261
266
|
4. Commit your changes (`git commit -am 'Add some feature'`)
|
262
267
|
5. Publish the branch (`git push origin my-new-feature`)
|
263
268
|
6. Create a new Pull Request
|
264
269
|
7. Profit! :white_check_mark:
|
265
270
|
|
266
|
-
|
271
|
+
You can test your workflow with changelog generator with [the skywinder/changelog_test repo](https://github.com/skywinder/changelog_test/).
|
267
272
|
|
268
273
|
## License
|
269
274
|
|
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "bundler"
|
3
4
|
require "bundler/gem_tasks"
|
4
5
|
require "rubocop/rake_task"
|
@@ -10,31 +11,10 @@ require "overcommit"
|
|
10
11
|
RuboCop::RakeTask.new
|
11
12
|
RSpec::Core::RakeTask.new(:rspec)
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
path = Pathname(f)
|
17
|
-
path.file? && path.readable?
|
18
|
-
end
|
19
|
-
|
20
|
-
next unless manpath
|
21
|
-
|
22
|
-
writable_man_path = Pathname(manpath).each_line.find do |line|
|
23
|
-
path = Pathname(line.chomp)
|
24
|
-
path.directory? && path.writable?
|
25
|
-
end
|
26
|
-
|
27
|
-
next unless writable_man_path
|
28
|
-
|
29
|
-
man_prefix = Pathname("#{writable_man_path.chomp}/man1")
|
30
|
-
man_pages = "man/git-*.1"
|
31
|
-
|
32
|
-
Pathname.glob(man_pages) do |path|
|
33
|
-
if path.exist? && man_prefix.exist? && man_prefix.writable?
|
34
|
-
FileUtils.cp(path, man_prefix + path.basename)
|
35
|
-
end
|
36
|
-
end
|
14
|
+
desc "When releasing the gem, re-fetch latest cacert.pem from curl.haxx.se. Developer task."
|
15
|
+
task :update_ssl_ca_file do
|
16
|
+
`pushd lib/github_changelog_generator/ssl_certs && curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem && popd`
|
37
17
|
end
|
38
18
|
|
39
|
-
task checks: [
|
40
|
-
task default: [
|
19
|
+
task checks: %i[rubocop rspec]
|
20
|
+
task default: %i[rubocop rspec]
|
data/bin/ghclgen
CHANGED
@@ -5,17 +5,18 @@ require "octokit"
|
|
5
5
|
require "faraday-http-cache"
|
6
6
|
require "logger"
|
7
7
|
require "active_support"
|
8
|
+
require "active_support/core_ext/object/blank"
|
8
9
|
require "json"
|
9
10
|
require "multi_json"
|
10
11
|
require "benchmark"
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
require "github_changelog_generator/helper"
|
14
|
+
require "github_changelog_generator/options"
|
15
|
+
require "github_changelog_generator/parser"
|
16
|
+
require "github_changelog_generator/parser_file"
|
17
|
+
require "github_changelog_generator/generator/generator"
|
18
|
+
require "github_changelog_generator/version"
|
19
|
+
require "github_changelog_generator/reader"
|
19
20
|
|
20
21
|
# The main module, where placed all classes (now, at least)
|
21
22
|
module GitHubChangelogGenerator
|
@@ -33,14 +34,10 @@ module GitHubChangelogGenerator
|
|
33
34
|
def run
|
34
35
|
log = @generator.compound_changelog
|
35
36
|
|
36
|
-
output_filename =
|
37
|
-
File.open(output_filename, "
|
37
|
+
output_filename = @options[:output].to_s
|
38
|
+
File.open(output_filename, "wb") { |file| file.write(log) }
|
38
39
|
puts "Done!"
|
39
40
|
puts "Generated log placed in #{Dir.pwd}/#{output_filename}"
|
40
41
|
end
|
41
42
|
end
|
42
|
-
|
43
|
-
if __FILE__ == $PROGRAM_NAME
|
44
|
-
GitHubChangelogGenerator::ChangelogGenerator.new.run
|
45
|
-
end
|
46
43
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative "../octo_fetcher"
|
3
4
|
require_relative "generator_generation"
|
4
5
|
require_relative "generator_fetcher"
|
@@ -35,16 +36,17 @@ module GitHubChangelogGenerator
|
|
35
36
|
detect_actual_closed_dates(@issues + @pull_requests)
|
36
37
|
end
|
37
38
|
|
38
|
-
|
39
|
+
ENCAPSULATED_CHARACTERS = %w(< > * _ \( \) [ ] #)
|
40
|
+
|
41
|
+
# Encapsulate characters to make Markdown look as expected.
|
39
42
|
#
|
40
43
|
# @param [String] string
|
41
44
|
# @return [String] encapsulated input string
|
42
45
|
def encapsulate_string(string)
|
43
|
-
string.gsub
|
46
|
+
string = string.gsub('\\', '\\\\')
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
string.gsub! char, "\\#{char}"
|
48
|
+
ENCAPSULATED_CHARACTERS.each do |char|
|
49
|
+
string = string.gsub(char, "\\#{char}")
|
48
50
|
end
|
49
51
|
|
50
52
|
string
|
@@ -55,14 +57,23 @@ module GitHubChangelogGenerator
|
|
55
57
|
# @param [Array] pull_requests List or PR's in new section
|
56
58
|
# @param [Array] issues List of issues in new section
|
57
59
|
# @param [String] newer_tag Name of the newer tag. Could be nil for `Unreleased` section
|
58
|
-
# @param [
|
60
|
+
# @param [Hash, nil] older_tag Older tag, used for the links. Could be nil for last tag.
|
59
61
|
# @return [String] Ready and parsed section
|
60
|
-
def create_log_for_tag(pull_requests, issues, newer_tag,
|
62
|
+
def create_log_for_tag(pull_requests, issues, newer_tag, older_tag = nil)
|
61
63
|
newer_tag_link, newer_tag_name, newer_tag_time = detect_link_tag_time(newer_tag)
|
62
64
|
|
63
65
|
github_site = options[:github_site] || "https://github.com"
|
64
66
|
project_url = "#{github_site}/#{options[:user]}/#{options[:project]}"
|
65
67
|
|
68
|
+
# If the older tag is nil, go back in time from the latest tag and find
|
69
|
+
# the SHA for the first commit.
|
70
|
+
older_tag_name =
|
71
|
+
if older_tag.nil?
|
72
|
+
@fetcher.commits_before(newer_tag_time).last["sha"]
|
73
|
+
else
|
74
|
+
older_tag["name"]
|
75
|
+
end
|
76
|
+
|
66
77
|
log = generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_name, project_url)
|
67
78
|
|
68
79
|
if options[:issues]
|
@@ -70,7 +81,7 @@ module GitHubChangelogGenerator
|
|
70
81
|
log += issues_to_log(issues, pull_requests)
|
71
82
|
end
|
72
83
|
|
73
|
-
if options[:pulls]
|
84
|
+
if options[:pulls] && options[:add_pr_wo_labels]
|
74
85
|
# Generate pull requests:
|
75
86
|
log += generate_sub_section(pull_requests, options[:merge_prefix])
|
76
87
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module GitHubChangelogGenerator
|
3
4
|
class Generator
|
4
5
|
MAX_THREAD_NUMBER = 25
|
@@ -77,7 +78,7 @@ module GitHubChangelogGenerator
|
|
77
78
|
issue["actual_date"] = commit["commit"]["author"]["date"]
|
78
79
|
|
79
80
|
# issue['actual_date'] = commit['author']['date']
|
80
|
-
rescue
|
81
|
+
rescue StandardError
|
81
82
|
puts "Warning: Can't fetch commit #{event['commit_id']}. It is probably referenced from another repo."
|
82
83
|
issue["actual_date"] = issue["closed_at"]
|
83
84
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module GitHubChangelogGenerator
|
3
4
|
class Generator
|
4
5
|
# Main function to start change log generation
|
@@ -20,7 +21,10 @@ module GitHubChangelogGenerator
|
|
20
21
|
|
21
22
|
log += File.read(options[:base]) if File.file?(options[:base])
|
22
23
|
|
23
|
-
|
24
|
+
credit_line = "\n\n\\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*"
|
25
|
+
log.gsub!(credit_line, "") # Remove old credit lines
|
26
|
+
log += credit_line
|
27
|
+
|
24
28
|
@log = log
|
25
29
|
end
|
26
30
|
|
@@ -64,7 +68,7 @@ module GitHubChangelogGenerator
|
|
64
68
|
log += if newer_tag_name.equal?(options[:unreleased_label])
|
65
69
|
"## [#{newer_tag_name}](#{release_url})\n\n"
|
66
70
|
else
|
67
|
-
"## [#{newer_tag_name}](#{release_url}) (#{time_string})\n"
|
71
|
+
"## [#{newer_tag_name}](#{release_url}) (#{time_string})\n\n"
|
68
72
|
end
|
69
73
|
|
70
74
|
if options[:compare_link] && older_tag_link
|
@@ -81,22 +85,21 @@ module GitHubChangelogGenerator
|
|
81
85
|
def generate_log_between_tags(older_tag, newer_tag)
|
82
86
|
filtered_issues, filtered_pull_requests = filter_issues_for_tags(newer_tag, older_tag)
|
83
87
|
|
84
|
-
older_tag_name = older_tag.nil? ? detect_since_tag : older_tag["name"]
|
85
|
-
|
86
88
|
if newer_tag.nil? && filtered_issues.empty? && filtered_pull_requests.empty?
|
87
89
|
# do not generate empty unreleased section
|
88
90
|
return ""
|
89
91
|
end
|
90
92
|
|
91
|
-
create_log_for_tag(filtered_pull_requests, filtered_issues, newer_tag,
|
93
|
+
create_log_for_tag(filtered_pull_requests, filtered_issues, newer_tag, older_tag)
|
92
94
|
end
|
93
95
|
|
94
|
-
#
|
96
|
+
# Filters issues and pull requests based on, respectively, `closed_at` and `merged_at`
|
97
|
+
# timestamp fields.
|
95
98
|
#
|
96
99
|
# @return [Array] filtered issues and pull requests
|
97
100
|
def filter_issues_for_tags(newer_tag, older_tag)
|
98
|
-
filtered_pull_requests = delete_by_time(@pull_requests, "
|
99
|
-
filtered_issues = delete_by_time(@issues, "
|
101
|
+
filtered_pull_requests = delete_by_time(@pull_requests, "merged_at", older_tag, newer_tag)
|
102
|
+
filtered_issues = delete_by_time(@issues, "closed_at", older_tag, newer_tag)
|
100
103
|
|
101
104
|
newer_tag_name = newer_tag.nil? ? nil : newer_tag["name"]
|
102
105
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module GitHubChangelogGenerator
|
3
4
|
class Generator
|
4
5
|
# delete all labels with labels from options[:exclude_labels] array
|
@@ -125,19 +126,17 @@ module GitHubChangelogGenerator
|
|
125
126
|
# @return [Array] filtered array of issues
|
126
127
|
def include_issues_by_labels(issues)
|
127
128
|
filtered_issues = filter_by_include_labels(issues)
|
128
|
-
filtered_issues
|
129
|
+
filtered_issues = filter_wo_labels(filtered_issues)
|
129
130
|
filtered_issues
|
130
131
|
end
|
131
132
|
|
132
133
|
# @return [Array] issues without labels or empty array if add_issues_wo_labels is false
|
133
134
|
def filter_wo_labels(issues)
|
134
135
|
if options[:add_issues_wo_labels]
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
return issues_wo_labels
|
136
|
+
issues
|
137
|
+
else
|
138
|
+
issues.select { |issue| issue["labels"].map { |l| l["name"] }.any? }
|
139
139
|
end
|
140
|
-
[]
|
141
140
|
end
|
142
141
|
|
143
142
|
def filter_by_include_labels(issues)
|
@@ -197,8 +196,8 @@ module GitHubChangelogGenerator
|
|
197
196
|
end
|
198
197
|
end
|
199
198
|
|
200
|
-
pull_requests.
|
201
|
-
|
199
|
+
pull_requests.reject! do |pr|
|
200
|
+
pr["merged_at"].nil?
|
202
201
|
end
|
203
202
|
|
204
203
|
pull_requests
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module GitHubChangelogGenerator
|
3
4
|
class Generator
|
4
5
|
# fetch, filter tags, fetch dates and sort them in time order
|
@@ -6,31 +7,48 @@ module GitHubChangelogGenerator
|
|
6
7
|
detect_since_tag
|
7
8
|
detect_due_tag
|
8
9
|
|
9
|
-
all_tags
|
10
|
-
included_tags = filter_excluded_tags(all_tags)
|
11
|
-
|
10
|
+
all_tags = @fetcher.get_all_tags
|
12
11
|
fetch_tags_dates(all_tags) # Creates a Hash @tag_times_hash
|
13
|
-
|
14
|
-
|
12
|
+
all_sorted_tags = sort_tags_by_date(all_tags)
|
13
|
+
|
14
|
+
@sorted_tags = filter_excluded_tags(all_sorted_tags)
|
15
|
+
@filtered_tags = get_filtered_tags(@sorted_tags)
|
16
|
+
|
17
|
+
# Because we need to properly create compare links, we need a sorted list
|
18
|
+
# of all filtered tags (including the excluded ones). We'll exclude those
|
19
|
+
# tags from section headers inside the mapping function.
|
20
|
+
section_tags = get_filtered_tags(all_sorted_tags)
|
15
21
|
|
16
|
-
@tag_section_mapping = build_tag_section_mapping(@filtered_tags
|
22
|
+
@tag_section_mapping = build_tag_section_mapping(section_tags, @filtered_tags)
|
17
23
|
|
18
24
|
@filtered_tags
|
19
25
|
end
|
20
26
|
|
21
|
-
# @param [Array]
|
22
|
-
# @param [Array]
|
27
|
+
# @param [Array] section_tags are the tags that need a subsection output
|
28
|
+
# @param [Array] filtered_tags is the list of filtered tags ordered from newest -> oldest
|
23
29
|
# @return [Hash] key is the tag to output, value is an array of [Left Tag, Right Tag]
|
24
30
|
# PRs to include in this section will be >= [Left Tag Date] and <= [Right Tag Date]
|
25
|
-
|
31
|
+
# rubocop:disable Style/For - for allows us to be more concise
|
32
|
+
def build_tag_section_mapping(section_tags, filtered_tags)
|
26
33
|
tag_mapping = {}
|
27
|
-
|
28
|
-
|
29
|
-
|
34
|
+
for i in 0..(section_tags.length - 1)
|
35
|
+
tag = section_tags[i]
|
36
|
+
|
37
|
+
# Don't create section header for the "since" tag
|
38
|
+
next if @since_tag && tag["name"] == @since_tag
|
39
|
+
|
40
|
+
# Don't create a section header for the first tag in between_tags
|
41
|
+
next if options[:between_tags] && tag == section_tags.last
|
42
|
+
|
43
|
+
# Don't create a section header for excluded tags
|
44
|
+
next unless filtered_tags.include?(tag)
|
45
|
+
|
46
|
+
older_tag = section_tags[i + 1]
|
30
47
|
tag_mapping[tag] = [older_tag, tag]
|
31
48
|
end
|
32
49
|
tag_mapping
|
33
50
|
end
|
51
|
+
# rubocop:enable Style/For
|
34
52
|
|
35
53
|
# Sort all tags by date, newest to oldest
|
36
54
|
def sort_tags_by_date(tags)
|
@@ -95,13 +113,12 @@ module GitHubChangelogGenerator
|
|
95
113
|
sections.first["version"] if sections && sections.any?
|
96
114
|
end
|
97
115
|
|
98
|
-
# Return tags after filtering tags in lists provided by option: --
|
116
|
+
# Return tags after filtering tags in lists provided by option: --exclude-tags
|
99
117
|
#
|
100
118
|
# @return [Array]
|
101
119
|
def get_filtered_tags(all_tags)
|
102
120
|
filtered_tags = filter_since_tag(all_tags)
|
103
|
-
|
104
|
-
filter_between_tags(filtered_tags)
|
121
|
+
filter_due_tag(filtered_tags)
|
105
122
|
end
|
106
123
|
|
107
124
|
# @param [Array] all_tags all tags
|
@@ -113,7 +130,7 @@ module GitHubChangelogGenerator
|
|
113
130
|
if all_tags.map { |t| t["name"] }.include? tag
|
114
131
|
idx = all_tags.index { |t| t["name"] == tag }
|
115
132
|
filtered_tags = if idx > 0
|
116
|
-
all_tags[0..idx
|
133
|
+
all_tags[0..idx]
|
117
134
|
else
|
118
135
|
[]
|
119
136
|
end
|
@@ -144,23 +161,6 @@ module GitHubChangelogGenerator
|
|
144
161
|
filtered_tags
|
145
162
|
end
|
146
163
|
|
147
|
-
# @param [Array] all_tags all tags
|
148
|
-
# @return [Array] filtered tags according :between_tags option
|
149
|
-
def filter_between_tags(all_tags)
|
150
|
-
filtered_tags = all_tags
|
151
|
-
tag_names = filtered_tags.map { |ft| ft["name"] }
|
152
|
-
|
153
|
-
if options[:between_tags]
|
154
|
-
options[:between_tags].each do |tag|
|
155
|
-
unless tag_names.include?(tag)
|
156
|
-
Helper.log.warn "Warning: can't find tag #{tag}, specified with --between-tags option."
|
157
|
-
end
|
158
|
-
end
|
159
|
-
filtered_tags = all_tags.select { |tag| options[:between_tags].include?(tag["name"]) }
|
160
|
-
end
|
161
|
-
filtered_tags
|
162
|
-
end
|
163
|
-
|
164
164
|
# @param [Array] all_tags all tags
|
165
165
|
# @return [Array] filtered tags according :exclude_tags or :exclude_tags_regex option
|
166
166
|
def filter_excluded_tags(all_tags)
|
@@ -177,18 +177,19 @@ module GitHubChangelogGenerator
|
|
177
177
|
|
178
178
|
def apply_exclude_tags(all_tags)
|
179
179
|
if options[:exclude_tags].is_a?(Regexp)
|
180
|
-
filter_tags_with_regex(all_tags, options[:exclude_tags])
|
180
|
+
filter_tags_with_regex(all_tags, options[:exclude_tags], "--exclude-tags")
|
181
181
|
else
|
182
182
|
filter_exact_tags(all_tags)
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
186
186
|
def apply_exclude_tags_regex(all_tags)
|
187
|
-
|
187
|
+
regex = Regexp.new(options[:exclude_tags_regex])
|
188
|
+
filter_tags_with_regex(all_tags, regex, "--exclude-tags-regex")
|
188
189
|
end
|
189
190
|
|
190
|
-
def filter_tags_with_regex(all_tags, regex)
|
191
|
-
warn_if_nonmatching_regex(all_tags)
|
191
|
+
def filter_tags_with_regex(all_tags, regex, regex_option_name)
|
192
|
+
warn_if_nonmatching_regex(all_tags, regex, regex_option_name)
|
192
193
|
all_tags.reject { |tag| regex =~ tag["name"] }
|
193
194
|
end
|
194
195
|
|
@@ -199,11 +200,10 @@ module GitHubChangelogGenerator
|
|
199
200
|
all_tags.reject { |tag| options[:exclude_tags].include?(tag["name"]) }
|
200
201
|
end
|
201
202
|
|
202
|
-
def warn_if_nonmatching_regex(all_tags)
|
203
|
-
unless all_tags.map { |t| t["name"] }.any? { |t|
|
203
|
+
def warn_if_nonmatching_regex(all_tags, regex, regex_option_name)
|
204
|
+
unless all_tags.map { |t| t["name"] }.any? { |t| regex =~ t }
|
204
205
|
Helper.log.warn "Warning: unable to reject any tag, using regex "\
|
205
|
-
"#{
|
206
|
-
"option."
|
206
|
+
"#{regex.inspect} in #{regex_option_name} option."
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|