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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +27 -22
  3. data/Rakefile +6 -26
  4. data/bin/ghclgen +1 -0
  5. data/lib/github_changelog_generator.rb +10 -13
  6. data/lib/github_changelog_generator/generator/generator.rb +19 -8
  7. data/lib/github_changelog_generator/generator/generator_fetcher.rb +2 -1
  8. data/lib/github_changelog_generator/generator/generator_generation.rb +11 -8
  9. data/lib/github_changelog_generator/generator/generator_processor.rb +7 -8
  10. data/lib/github_changelog_generator/generator/generator_tags.rb +41 -41
  11. data/lib/github_changelog_generator/helper.rb +1 -0
  12. data/lib/github_changelog_generator/octo_fetcher.rb +25 -4
  13. data/lib/github_changelog_generator/options.rb +50 -57
  14. data/lib/github_changelog_generator/parser.rb +16 -15
  15. data/lib/github_changelog_generator/parser_file.rb +4 -3
  16. data/lib/github_changelog_generator/reader.rb +1 -0
  17. data/lib/github_changelog_generator/ssl_certs/cacert.pem +4043 -0
  18. data/lib/github_changelog_generator/task.rb +3 -2
  19. data/lib/github_changelog_generator/version.rb +2 -1
  20. data/man/git-generate-changelog.1 +3 -3
  21. data/man/git-generate-changelog.1.html +3 -7
  22. data/man/git-generate-changelog.html +0 -4
  23. data/man/git-generate-changelog.md +6 -6
  24. data/spec/spec_helper.rb +2 -3
  25. data/spec/unit/generator/generator_generation_spec.rb +17 -0
  26. data/spec/unit/generator/generator_processor_spec.rb +64 -13
  27. data/spec/unit/generator/generator_tags_spec.rb +123 -65
  28. data/spec/unit/octo_fetcher_spec.rb +17 -2
  29. data/spec/unit/options_spec.rb +1 -0
  30. data/spec/unit/parse_file_spec.rb +6 -6
  31. data/spec/unit/parser_spec.rb +1 -0
  32. data/spec/unit/reader_spec.rb +1 -0
  33. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits_before/when_API_is_valid/returns_commits.json +1 -0
  34. metadata +14 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7b9a2c015dc8e19a8cb9cb6988775f11362ca6d9
4
- data.tar.gz: 52aecd1cfe47d43818081c61473271a95003c672
3
+ metadata.gz: 90e44c8d99a9213765a5d46605dd584956f79ca0
4
+ data.tar.gz: e42720ae60fc9c8096c41cb51456e0aacdcc8b69
5
5
  SHA512:
6
- metadata.gz: ed46e2b1953fddca0d6eb5cd99ecd293a7cbf0900bc661986401d7b4d1cff1c7c74a0e10da1f6abfb0f3a71ba07a9877df2f3c0727ec818168034b7e914aae54
7
- data.tar.gz: c665a3f40ecfbf48ec81976946e7444bb97e4e107db6ed379a3d792f6db46442e642acbc84844371a6849773b5d14be3315a9c1b280d91e0bbb2c7fa8b60ab0c
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 automate changelog generation** - This gem generates 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
+ **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 now you don't have to fill your `CHANGELOG.md` manually: just run the script, relax and take a cup of :coffee: before your next release! :tada:
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
- >### *What’s the point of a change log?*
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
- > :arrow_right: *[http://keepachangelog.com](http://keepachangelog.com)*
37
+ :arrow_right: *[http://keepachangelog.com](http://keepachangelog.com)*
37
38
 
38
39
  ## Installation
39
40
 
40
- gem install github_changelog_generator
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
- github_changelog_generator -u skywinder -p ActionSheetPicker-3.0
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
- github_changelog_generator
78
+ github_changelog_generator
78
79
 
79
80
  - Or, run this from anywhere:
80
- - `github_changelog_generator -u github_username -p github_project`
81
- - `github_changelog_generator github_username/github_project`
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
- github_changelog_generator --github-site="https://github.yoursite.com" \
86
- --github-api="https://github.yoursite.com/api/v3/"
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 only 50 unauthenticated requests per hour.
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
- export CHANGELOG_GITHUB_TOKEN="«your-40-digit-github-token»"
120
+ export CHANGELOG_GITHUB_TOKEN="«your-40-digit-github-token»"
120
121
 
121
- So, if you got an error like this:
122
- >! /Library/Ruby/Gems/2.0.0/gems/github_api-0.12.2/lib/github_api/response/raise_error.rb:14:in `on_complete'
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 I found a closed bug, it's very useful know which release fixed it.
212
- In this case, you can easily find the issue by \# in `CHANGELOG.md`.
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 is ideal for end-users.
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] (https://github.com/skywinder/Github-Changelog-Generator/fork)
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
- *To test your workflow with changelog generator, you can use [test repo](https://github.com/skywinder/changelog_test/)*
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
- task :copy_man_page_to_manpath do |_t|
14
- known_manpath_paths = %w(/etc/manpath.config /etc/manpaths)
15
- manpath = known_manpath_paths.find do |f|
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: [:rubocop, :rspec]
40
- task default: [:rubocop, :rspec]
19
+ task checks: %i[rubocop rspec]
20
+ task default: %i[rubocop rspec]
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -U
2
2
  # frozen_string_literal: true
3
+
3
4
  require "github_changelog_generator"
4
5
  GitHubChangelogGenerator::CLI.start(ARGV)
@@ -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
- require_relative "github_changelog_generator/helper"
13
- require_relative "github_changelog_generator/options"
14
- require_relative "github_changelog_generator/parser"
15
- require_relative "github_changelog_generator/parser_file"
16
- require_relative "github_changelog_generator/generator/generator"
17
- require_relative "github_changelog_generator/version"
18
- require_relative "github_changelog_generator/reader"
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 = (@options[:output]).to_s
37
- File.open(output_filename, "w") { |file| file.write(log) }
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
- # Encapsulate characters to make markdown look as expected.
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
- encpas_chars = %w(< > * _ \( \) [ ] #)
46
- encpas_chars.each do |char|
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 [String] older_tag_name Older tag, used for the links. Could be nil for last tag.
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, older_tag_name = nil)
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
- log += "\n\n\\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*"
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, older_tag_name)
93
+ create_log_for_tag(filtered_pull_requests, filtered_issues, newer_tag, older_tag)
92
94
  end
93
95
 
94
- # Apply all filters to issues and pull requests
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, "actual_date", older_tag, newer_tag)
99
- filtered_issues = delete_by_time(@issues, "actual_date", older_tag, newer_tag)
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 |= filter_wo_labels(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
- issues_wo_labels = issues.select do |issue|
136
- !issue["labels"].map { |l| l["name"] }.any?
137
- end
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.select! do |pr|
201
- !pr["merged_at"].nil?
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 = @fetcher.get_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
- @sorted_tags = sort_tags_by_date(included_tags)
14
- @filtered_tags = get_filtered_tags(included_tags)
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, sorted_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] filtered_tags are the tags that need a subsection output
22
- # @param [Array] all_tags is the list of all tags ordered from newest -> oldest
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
- def build_tag_section_mapping(filtered_tags, all_tags)
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
- filtered_tags.each do |tag|
28
- older_tag_idx = all_tags.index(tag) + 1
29
- older_tag = all_tags[older_tag_idx]
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: --between-tags & --exclude-tags
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
- filtered_tags = filter_due_tag(filtered_tags)
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 - 1]
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
- filter_tags_with_regex(all_tags, Regexp.new(options[:exclude_tags_regex]))
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| options[:exclude_tags] =~ 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
- "#{options[:exclude_tags].inspect} in --exclude-tags "\
206
- "option."
206
+ "#{regex.inspect} in #{regex_option_name} option."
207
207
  end
208
208
  end
209
209