github_changelog_generator 1.16.4 → 1.17.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +52 -16
  3. data/bin/github_changelog_generator +1 -1
  4. data/lib/github_changelog_generator/argv_parser.rb +2 -2
  5. data/lib/github_changelog_generator/file_parser_chooser.rb +27 -0
  6. data/lib/github_changelog_generator/generator/entry.rb +3 -3
  7. data/lib/github_changelog_generator/generator/generator.rb +15 -10
  8. data/lib/github_changelog_generator/generator/generator_fetcher.rb +22 -24
  9. data/lib/github_changelog_generator/generator/generator_processor.rb +14 -24
  10. data/lib/github_changelog_generator/generator/generator_tags.rb +24 -34
  11. data/lib/github_changelog_generator/generator/section.rb +9 -4
  12. data/lib/github_changelog_generator/octo_fetcher.rb +25 -8
  13. data/lib/github_changelog_generator/options.rb +12 -2
  14. data/lib/github_changelog_generator/parser.rb +4 -4
  15. data/lib/github_changelog_generator/parser_file.rb +0 -24
  16. data/lib/github_changelog_generator/task.rb +2 -2
  17. data/lib/github_changelog_generator/version.rb +1 -1
  18. data/lib/github_changelog_generator.rb +18 -16
  19. data/man/git-generate-changelog.html +2 -2
  20. data/spec/github_changelog_generator_spec.rb +32 -0
  21. data/spec/unit/generator/entry_spec.rb +2 -2
  22. data/spec/unit/generator/generator_processor_spec.rb +61 -0
  23. data/spec/unit/generator/generator_spec.rb +151 -0
  24. data/spec/unit/generator/generator_tags_spec.rb +1 -1
  25. data/spec/unit/generator/section_spec.rb +9 -0
  26. data/spec/unit/octo_fetcher_spec.rb +8 -8
  27. data/spec/unit/{parse_file_spec.rb → parser_file_spec.rb} +35 -15
  28. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits/when_API_is_valid/returns_commits.json +1 -1
  29. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits_before/when_API_is_valid/returns_commits.json +1 -1
  30. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issue_with_proper_key/values.json +1 -1
  31. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues.json +1 -1
  32. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues_with_labels.json +1 -1
  33. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_request_with_proper_key/values.json +1 -1
  34. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_requests_with_labels.json +1 -1
  35. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid.json +1 -1
  36. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_correct_pull_request_keys.json +1 -1
  37. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_pull_requests.json +1 -1
  38. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid.json +1 -1
  39. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid/returns_commit.json +1 -1
  40. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid.json +1 -1
  41. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid/returns_date.json +1 -1
  42. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid.json +1 -1
  43. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid/populates_issues.json +1 -1
  44. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid.json +1 -1
  45. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags.json +1 -1
  46. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags_count.json +1 -1
  47. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid.json +1 -1
  48. metadata +12 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36cb65499e406ed1e554d4239e9d36806888d1ca9c3fe0f47e0e8e49053dd2b9
4
- data.tar.gz: 991b1251d601d2504d2c610087b43d0deaebbe7f031987eda8dc5a84e7ac46cb
3
+ metadata.gz: e07c565356c5e5e983b771c56833c9579afd0d174ca6930a70699e38486afb8d
4
+ data.tar.gz: f9fca1bd85bef606332a6da07c01f093adbecd7a26256c6826a593d8b15a5ebb
5
5
  SHA512:
6
- metadata.gz: d5d733ce47da1d762b8dd3c4513989955ecd1adfe973ba044baef80fec2917d621841e9779d97b8298f04cd5b05d64c97d78cc872ba73d9b46ed2db3ae709344
7
- data.tar.gz: ecfad19e0066fb2e9ddbdbc6c514f1c86bf57c6ff0704999adc05a181812fc182469ad77ba7d9fdabe1cbf06adff20680df06b0121c35e602c27222cab983106
6
+ metadata.gz: a312859c596e52e04c52d9fef05b2552f64c6efc8117b7c948451566ac2de67416407d3aaed0a675ece080cbf6ebda41b0ed65db3154427525f8896e6829ba94
7
+ data.tar.gz: 3f44449ed200a68d14670f471a81a36932a2ec171b6b8c44362bc554f3d2aadf484e882eb61888e599d20df362e851d850b861103441ce0d8be3df975b8cc128
data/README.md CHANGED
@@ -1,6 +1,5 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/github_changelog_generator.svg)](http://badge.fury.io/rb/github_changelog_generator)
2
- [![CircleCI](https://circleci.com/gh/github-changelog-generator/github-changelog-generator.svg?style=svg)](https://circleci.com/gh/github-changelog-generator/github-changelog-generator)
3
- [![Inline docs](http://inch-ci.org/github/github-changelog-generator/github-changelog-generator.svg)](http://inch-ci.org/github/github-changelog-generator/github-changelog-generator)
2
+ [![Ruby CI](https://github.com/github-changelog-generator/github-changelog-generator/actions/workflows/test.yml/badge.svg)](https://github.com/github-changelog-generator/github-changelog-generator/actions/workflows/test.yml)
4
3
  [![Join the chat at https://gitter.im/github-changelog-generator/chat](https://badges.gitter.im/github-changelog-generator/chat.svg)](https://gitter.im/github-changelog-generator/chat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5
4
 
6
5
  # github-changelog-generator ![GitHub Logo](../master/images/logo.jpg)
@@ -12,14 +11,14 @@ To update TOC, please run:
12
11
  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
13
12
  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
14
13
 
15
-
16
14
  - [Changelog generation has never been so easy](#changelog-generation-has-never-been-so-easy)
17
15
  - [*What’s the point of a changelog?*](#whats-the-point-of-a-changelog)
18
16
  - [*Why should I care?*](#why-should-i-care)
19
17
  - [Installation](#installation)
20
- - [Running with Docker](#running-with-docker)
21
- - [Output example](#output-example)
22
18
  - [Usage](#usage)
19
+ - [Running with CLI:](#running-with-cli)
20
+ - [Running with Docker](#running-with-docker)
21
+ - [Output example](#output-example)
23
22
  - [Params](#params)
24
23
  - [Params File](#params-file)
25
24
  - [GitHub token](#github-token)
@@ -29,9 +28,12 @@ To update TOC, please run:
29
28
  - [Using the summary section feature](#using-the-summary-section-feature)
30
29
  - [Alternatives](#alternatives)
31
30
  - [Projects using this library](#projects-using-this-library)
31
+ - [Practical Use Cases](#practical-use-cases)
32
+ - [Creating GitHub Release Notes](#creating-github-release-notes)
32
33
  - [Am I missing some essential feature?](#am-i-missing-some-essential-feature)
33
34
  - [FAQ](#faq)
34
35
  - [Contributing](#contributing)
36
+ - [Contact us](#contact-us)
35
37
  - [License](#license)
36
38
 
37
39
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -99,30 +101,30 @@ This generates a `CHANGELOG.md`, with pretty Markdown formatting.
99
101
 
100
102
  ## Output example
101
103
 
102
- - Look at **[CHANGELOG.md](https://github.com/github-changelog-generator/Github-Changelog-Generator/blob/master/CHANGELOG.md)** for this project
104
+ - Look at **[CHANGELOG.md](https://github.com/github-changelog-generator/github-changelog-generator/blob/master/CHANGELOG.md)** for this project
103
105
  - [ActionSheetPicker-3.0/CHANGELOG.md](https://github.com/skywinder/ActionSheetPicker-3.0/blob/develop/CHANGELOG.md) was generated by command:
104
106
 
105
107
  $ github_changelog_generator -u github-changelog-generator -p ActionSheetPicker-3.0
106
108
 
107
109
  - In general, it looks like this:
108
110
 
109
- > ## [1.2.5](https://github.com/github-changelog-generator/Github-Changelog-Generator/tree/1.2.5) (2015-01-15)
111
+ > ## [1.2.5](https://github.com/github-changelog-generator/github-changelog-generator/tree/1.2.5) (2015-01-15)
110
112
  >
111
- > [Full Changelog](https://github.com/github-changelog-generator/Github-Changelog-Generator/compare/1.2.4...1.2.5)
113
+ > [Full Changelog](https://github.com/github-changelog-generator/github-changelog-generator/compare/1.2.4...1.2.5)
112
114
  >
113
115
  > **Implemented enhancements:**
114
116
  >
115
- > - Use milestone to specify in which version bug was fixed [\#22](https://github.com/github-changelog-generator/Github-Changelog-Generator/issues/22)
117
+ > - Use milestone to specify in which version bug was fixed [\#22](https://github.com/github-changelog-generator/github-changelog-generator/issues/22)
116
118
  >
117
119
  > **Fixed bugs:**
118
120
  >
119
- > - Error when trying to generate log for repo without tags [\#32](https://github.com/github-changelog-generator/Github-Changelog-Generator/issues/32)
121
+ > - Error when trying to generate log for repo without tags [\#32](https://github.com/github-changelog-generator/github-changelog-generator/issues/32)
120
122
  >
121
123
  > **Merged pull requests:**
122
124
  >
123
- > - PrettyPrint class is included using lowercase 'pp' [\#43](https://github.com/github-changelog-generator/Github-Changelog-Generator/pull/43) ([schwing](https://github.com/schwing))
125
+ > - PrettyPrint class is included using lowercase 'pp' [\#43](https://github.com/github-changelog-generator/github-changelog-generator/pull/43) ([schwing](https://github.com/schwing))
124
126
  >
125
- > - support enterprise github via command line options [\#42](https://github.com/github-changelog-generator/Github-Changelog-Generator/pull/42) ([glenlovett](https://github.com/glenlovett))
127
+ > - support enterprise github via command line options [\#42](https://github.com/github-changelog-generator/github-changelog-generator/pull/42) ([glenlovett](https://github.com/glenlovett))
126
128
 
127
129
  ### Params
128
130
 
@@ -219,6 +221,7 @@ You can look for params names from the [parser source code (#setup_parser)](http
219
221
  - Bug fixes (issues labeled `bug`) :beetle:
220
222
  - Enhancements (issues labeled `enhancement`) :star2:
221
223
  - Issues (closed issues with no labels) :non-potable_water:
224
+ - Plus any additional custom label-to-section mappings you want :gear:
222
225
 
223
226
  - Manually include or exclude issues by labels :wrench:
224
227
  - Customize lots more! Tweak the changelog to fit your preferences :tophat:
@@ -253,24 +256,46 @@ Hello, World! :tada:
253
256
 
254
257
  ### Alternatives
255
258
 
256
- Here is a [wikipage list of alternatives](https://github.com/github-changelog-generator/Github-Changelog-Generator/wiki/Alternatives) that I found. But none satisfied my requirements.
259
+ Here is a [wikipage list of alternatives](https://github.com/github-changelog-generator/github-changelog-generator/wiki/Alternatives) that I found. But none satisfied my requirements.
257
260
 
258
261
  *If you know other projects, feel free to edit this Wiki page!*
259
262
 
260
263
 
261
264
  ### Projects using this library
262
265
 
263
- Here's a [wikipage list of projects](https://github.com/github-changelog-generator/Github-Changelog-Generator/wiki/Projects-using-Github-Changelog-Generator).
266
+ Here's a [wikipage list of projects](https://github.com/github-changelog-generator/github-changelog-generator/wiki/Projects-using-GitHub-Changelog-Generator).
264
267
 
265
268
  If you've used this project in a live app, please let me know! Nothing makes me happier than seeing someone else take my work and go wild with it.
266
269
 
267
- *If you are using `github_changelog_generator` to generate your project's changelog, or know of other projects using it, please [add it to this list](https://github.com/github-changelog-generator/github-changelog-generator/wiki/Projects-using-Github-Changelog-Generator).*
270
+ *If you are using `github_changelog_generator` to generate your project's changelog, or know of other projects using it, please [add it to this list](https://github.com/github-changelog-generator/github-changelog-generator/wiki/Projects-using-GitHub-Changelog-Generator).*
271
+
272
+ ## Practical Use Cases
273
+
274
+ ### Creating GitHub Release Notes
275
+
276
+ `github_changelog_generator` can be used in combination with the [github cli](https://cli.github.com/) to create release notes. Use the `--since-tag` and `--output` options of `github_changelog_generator` to create a changelog for the current release and store the results in a file. In the
277
+ example below, version `2.0.0` is the current release and version `1.0.0` is the previous release.
278
+
279
+ ```
280
+ mkdir -p build
281
+ github_changelog_generator \
282
+ --since-tag 1.0.0 \
283
+ --output build/changelog.md
284
+ ```
285
+
286
+ Then use the [release create](https://cli.github.com/manual/gh_release_create) feature of the github cli to create a new github release
287
+
288
+ ```
289
+ gh release create 2.0.0 \
290
+ --notes-file build/changelog.md \
291
+ --title 2.0.0
292
+ ```
268
293
 
269
294
  ## Am I missing some essential feature?
270
295
 
271
296
  - **Nothing is impossible!**
272
297
 
273
- - Open an [issue](https://github.com/github-changelog-generator/Github-Changelog-Generator/issues/new) and let's make the generator better together!
298
+ - Open an [issue](https://github.com/github-changelog-generator/github-changelog-generator/issues/new/choose) and let's make the generator better together!
274
299
 
275
300
  - *Bug reports, feature requests, patches, and well-wishes are always welcome.* :heavy_exclamation_mark:
276
301
 
@@ -286,6 +311,17 @@ I'm not trying to compare the quality of handwritten and auto-generated logs. Th
286
311
 
287
312
  An auto-generated changelog really helps, even if you manually fill in the release notes!
288
313
 
314
+ - **I want to define my own label-to-section mapping, how can I do it?**
315
+
316
+ This is possible using either the ``add-sections`` or ``configure-sections``
317
+ entry in ``.github_changelog_generator``. For example, to add a single new
318
+ entry called "Maintenance" that will catch PRs tagged with your ``maintenance``
319
+ label, you can add to ``.github_changelog_generator`` the line:
320
+ ```
321
+ add-sections= {"maintenance":{"prefix":"**Project maintenance**","labels":["maintenance"]}}
322
+ ```
323
+ A similar approach can be used via ``configure-sections`` to set all section
324
+ properties (including adding new ones!).
289
325
 
290
326
  - ***My Ruby version is very old, can I use this?***
291
327
 
@@ -1,4 +1,4 @@
1
- #! /usr/bin/env ruby
1
+ #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require_relative "../lib/github_changelog_generator"
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "optparse"
4
- require "github_changelog_generator/version"
4
+ require_relative "version"
5
5
 
6
6
  module GitHubChangelogGenerator
7
7
  class ArgvParser
@@ -21,7 +21,7 @@ module GitHubChangelogGenerator
21
21
  def parser
22
22
  @parser ||= OptionParser.new do |opts| # rubocop:disable Metrics/BlockLength
23
23
  opts.banner = "Usage: github_changelog_generator --user USER --project PROJECT [options]"
24
- opts.on("-u", "--user USER", "Username of the owner of the target GitHub repo OR the namespace of target Github repo if owned by an organization.") do |last|
24
+ opts.on("-u", "--user USER", "Username of the owner of the target GitHub repo OR the namespace of target GitHub repo if owned by an organization.") do |last|
25
25
  options[:user] = last
26
26
  end
27
27
  opts.on("-p", "--project PROJECT", "Name of project on GitHub.") do |last|
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+
5
+ module GitHubChangelogGenerator
6
+ class FileParserChooser
7
+ def initialize(options)
8
+ @options = options
9
+ @config_file = Pathname.new(options[:config_file])
10
+ end
11
+
12
+ def parse!(_argv)
13
+ return nil unless (path = resolve_path)
14
+
15
+ ParserFile.new(@options, File.open(path)).parse!
16
+ end
17
+
18
+ def resolve_path
19
+ return @config_file if @config_file.exist?
20
+
21
+ path = @config_file.expand_path
22
+ return path if File.exist?(path)
23
+
24
+ nil
25
+ end
26
+ end
27
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "github_changelog_generator/generator/section"
3
+ require_relative "section"
4
4
 
5
5
  module GitHubChangelogGenerator
6
6
  # This class generates the content for a single changelog entry. An entry is
@@ -72,7 +72,7 @@ module GitHubChangelogGenerator
72
72
  def parse_sections(sections_desc)
73
73
  require "json"
74
74
 
75
- sections_desc = sections_desc.to_json if sections_desc.class == Hash
75
+ sections_desc = sections_desc.to_json if sections_desc.instance_of?(Hash)
76
76
 
77
77
  begin
78
78
  sections_json = JSON.parse(sections_desc)
@@ -175,7 +175,7 @@ module GitHubChangelogGenerator
175
175
  # default sections followed by any --add-sections sections in
176
176
  # user-defined order, or --configure-sections in user-defined order.
177
177
  # Ignore the order of the issue labels from github which cannot be
178
- # controled by the user.
178
+ # controlled by the user.
179
179
  @sections.each do |section|
180
180
  unless (section.labels & label_names).empty?
181
181
  section.issues << issue
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "github_changelog_generator/octo_fetcher"
4
- require "github_changelog_generator/generator/generator_fetcher"
5
- require "github_changelog_generator/generator/generator_processor"
6
- require "github_changelog_generator/generator/generator_tags"
7
- require "github_changelog_generator/generator/entry"
8
- require "github_changelog_generator/generator/section"
3
+ require_relative "../octo_fetcher"
4
+ require_relative "generator_fetcher"
5
+ require_relative "generator_processor"
6
+ require_relative "generator_tags"
7
+ require_relative "entry"
8
+ require_relative "section"
9
9
 
10
10
  module GitHubChangelogGenerator
11
11
  # Default error for ChangelogGenerator
@@ -76,7 +76,7 @@ module GitHubChangelogGenerator
76
76
 
77
77
  if newer_tag.nil? && filtered_issues.empty? && filtered_pull_requests.empty?
78
78
  # do not generate empty unreleased section
79
- return ""
79
+ return +""
80
80
  end
81
81
 
82
82
  newer_tag_link, newer_tag_name, newer_tag_time = detect_link_tag_time(newer_tag)
@@ -128,7 +128,7 @@ module GitHubChangelogGenerator
128
128
  end
129
129
 
130
130
  def generate_unreleased_entry
131
- entry = ""
131
+ entry = +""
132
132
  if options[:unreleased]
133
133
  start_tag = @filtered_tags[0] || @sorted_tags.last
134
134
  unreleased_entry = generate_entry_between_tags(start_tag, nil)
@@ -149,7 +149,12 @@ module GitHubChangelogGenerator
149
149
 
150
150
  fetch_events_for_issues_and_pr
151
151
  detect_actual_closed_dates(@issues + @pull_requests)
152
- add_first_occurring_tag_to_prs(@sorted_tags, @pull_requests)
152
+ prs_left = add_first_occurring_tag_to_prs(@sorted_tags, @pull_requests)
153
+
154
+ # PRs in prs_left will be untagged, not in release branch, and not
155
+ # rebased. They should not be included in the changelog as they probably
156
+ # have been merged to a branch other than the release branch.
157
+ @pull_requests -= prs_left
153
158
  nil
154
159
  end
155
160
 
@@ -166,7 +171,7 @@ module GitHubChangelogGenerator
166
171
  # messages of the same wording are removed.
167
172
  # @param log [String]
168
173
  def insert_fixed_string(log)
169
- ins = ""
174
+ ins = +""
170
175
  ins += @options[:frontmatter] if @options[:frontmatter]
171
176
  ins += "#{@options[:header]}\n\n"
172
177
  log.insert(0, ins)
@@ -48,11 +48,10 @@ module GitHubChangelogGenerator
48
48
  prs_left = associate_tagged_prs(tags, prs, total)
49
49
  prs_left = associate_release_branch_prs(prs_left, total)
50
50
  prs_left = associate_rebase_comment_prs(tags, prs_left, total) if prs_left.any?
51
- # PRs in prs_left will be untagged, not in release branch, and not
52
- # rebased. They should not be included in the changelog as they probably
53
- # have been merged to a branch other than the release branch.
54
- @pull_requests -= prs_left
51
+
55
52
  Helper.log.info "Associating PRs with tags: #{total}/#{total}"
53
+
54
+ prs_left
56
55
  end
57
56
 
58
57
  # Associate merged PRs by the merge SHA contained in each tag. If the
@@ -80,7 +79,7 @@ module GitHubChangelogGenerator
80
79
  print("Associating PRs with tags: #{i}/#{total}\r") if @options[:verbose]
81
80
  end
82
81
  else
83
- # Either there were no events or no merged event. Github's api can be
82
+ # Either there were no events or no merged event. GitHub's api can be
84
83
  # weird like that apparently. Check for a rebased comment before erroring.
85
84
  no_events_pr = associate_rebase_comment_prs(tags, [pr], total)
86
85
  raise StandardError, "No merge sha found for PR #{pr['number']} via the GitHub API" unless no_events_pr.empty?
@@ -154,15 +153,15 @@ module GitHubChangelogGenerator
154
153
  # Fill :actual_date parameter of specified issue by closed date of the commit, if it was closed by commit.
155
154
  # @param [Hash] issue
156
155
  def find_closed_date_by_commit(issue)
157
- unless issue["events"].nil?
158
- # if it's PR -> then find "merged event", in case of usual issue -> fond closed date
159
- compare_string = issue["merged_at"].nil? ? "closed" : "merged"
160
- # reverse! - to find latest closed event. (event goes in date order)
161
- issue["events"].reverse!.each do |event|
162
- if event["event"].eql? compare_string
163
- set_date_from_event(event, issue)
164
- break
165
- end
156
+ return if issue["events"].nil?
157
+
158
+ # if it's PR -> then find "merged event", in case of usual issue -> found closed date
159
+ compare_string = issue["merged_at"].nil? ? "closed" : "merged"
160
+ # reverse! - to find latest closed event. (event goes in date order)
161
+ issue["events"].reverse!.each do |event|
162
+ if event["event"] == compare_string
163
+ set_date_from_event(event, issue)
164
+ break
166
165
  end
167
166
  end
168
167
  # TODO: assert issues, that remain without 'actual_date' hash for some reason.
@@ -175,17 +174,16 @@ module GitHubChangelogGenerator
175
174
  def set_date_from_event(event, issue)
176
175
  if event["commit_id"].nil?
177
176
  issue["actual_date"] = issue["closed_at"]
178
- else
179
- begin
180
- commit = @fetcher.fetch_commit(event["commit_id"])
181
- issue["actual_date"] = commit["commit"]["author"]["date"]
182
-
183
- # issue['actual_date'] = commit['author']['date']
184
- rescue StandardError
185
- puts "Warning: Can't fetch commit #{event['commit_id']}. It is probably referenced from another repo."
186
- issue["actual_date"] = issue["closed_at"]
187
- end
177
+ return
188
178
  end
179
+
180
+ commit = @fetcher.fetch_commit(event["commit_id"])
181
+ issue["actual_date"] = commit["commit"]["author"]["date"]
182
+
183
+ # issue['actual_date'] = commit['author']['date']
184
+ rescue StandardError
185
+ puts "Warning: Can't fetch commit #{event['commit_id']}. It is probably referenced from another repo."
186
+ issue["actual_date"] = issue["closed_at"]
189
187
  end
190
188
 
191
189
  private
@@ -46,19 +46,13 @@ module GitHubChangelogGenerator
46
46
  # @return [Array] issues with milestone #tag_name
47
47
  def find_issues_to_add(all_issues, tag_name)
48
48
  all_issues.select do |issue|
49
- if issue["milestone"].nil?
49
+ if (milestone = issue["milestone"]).nil?
50
+ false
51
+ # check, that this milestone in tag list:
52
+ elsif (tag = find_tag_for_milestone(milestone)).nil?
50
53
  false
51
54
  else
52
- # check, that this milestone in tag list:
53
- milestone_is_tag = @filtered_tags.find do |tag|
54
- tag["name"] == issue["milestone"]["title"]
55
- end
56
-
57
- if milestone_is_tag.nil?
58
- false
59
- else
60
- issue["milestone"]["title"] == tag_name
61
- end
55
+ tag["name"] == tag_name
62
56
  end
63
57
  end
64
58
  end
@@ -67,18 +61,22 @@ module GitHubChangelogGenerator
67
61
  def remove_issues_in_milestones(filtered_issues)
68
62
  filtered_issues.select! do |issue|
69
63
  # leave issues without milestones
70
- if issue["milestone"].nil?
64
+ if (milestone = issue["milestone"]).nil?
71
65
  true
72
66
  # remove issues of open milestones if option is set
73
- elsif issue["milestone"]["state"] == "open"
67
+ elsif milestone["state"] == "open"
74
68
  @options[:issues_of_open_milestones]
75
69
  else
76
70
  # check, that this milestone in tag list:
77
- @filtered_tags.find { |tag| tag["name"] == issue["milestone"]["title"] }.nil?
71
+ find_tag_for_milestone(milestone).nil?
78
72
  end
79
73
  end
80
74
  end
81
75
 
76
+ def find_tag_for_milestone(milestone)
77
+ @filtered_tags.find { |tag| tag["name"] == milestone["title"] }
78
+ end
79
+
82
80
  # Method filter issues, that belong only specified tag range
83
81
  #
84
82
  # @param [Array] issues issues to filter
@@ -133,19 +131,11 @@ module GitHubChangelogGenerator
133
131
  end
134
132
 
135
133
  def tag_older_new_tag?(newer_tag_time, time)
136
- if newer_tag_time.nil?
137
- true
138
- else
139
- time <= newer_tag_time
140
- end
134
+ newer_tag_time.nil? || time <= newer_tag_time
141
135
  end
142
136
 
143
137
  def tag_newer_old_tag?(older_tag_time, time)
144
- if older_tag_time.nil?
145
- true
146
- else
147
- time > older_tag_time
148
- end
138
+ older_tag_time.nil? || time > older_tag_time
149
139
  end
150
140
 
151
141
  # Include issues with labels, specified in :include_labels
@@ -7,7 +7,7 @@ module GitHubChangelogGenerator
7
7
  since_tag
8
8
  due_tag
9
9
 
10
- all_tags = @fetcher.get_all_tags
10
+ all_tags = @fetcher.fetch_all_tags
11
11
  fetch_tags_dates(all_tags) # Creates a Hash @tag_times_hash
12
12
  all_sorted_tags = sort_tags_by_date(all_tags)
13
13
 
@@ -119,41 +119,29 @@ module GitHubChangelogGenerator
119
119
  # @param [Array] all_tags all tags
120
120
  # @return [Array] filtered tags according :since_tag option
121
121
  def filter_since_tag(all_tags)
122
- filtered_tags = all_tags
123
- tag = since_tag
124
- if tag
125
- if all_tags.map { |t| t["name"] }.include? tag
126
- idx = all_tags.index { |t| t["name"] == tag }
127
- filtered_tags = if idx
128
- all_tags[0..idx]
129
- else
130
- []
131
- end
132
- else
133
- raise ChangelogGeneratorError, "Error: can't find tag #{tag}, specified with --since-tag option."
134
- end
122
+ return all_tags unless (tag = since_tag)
123
+
124
+ raise ChangelogGeneratorError, "Error: can't find tag #{tag}, specified with --since-tag option." if all_tags.none? { |t| t["name"] == tag }
125
+
126
+ if (idx = all_tags.index { |t| t["name"] == tag })
127
+ all_tags[0..idx]
128
+ else
129
+ []
135
130
  end
136
- filtered_tags
137
131
  end
138
132
 
139
133
  # @param [Array] all_tags all tags
140
134
  # @return [Array] filtered tags according :due_tag option
141
135
  def filter_due_tag(all_tags)
142
- filtered_tags = all_tags
143
- tag = due_tag
144
- if tag
145
- if all_tags.any? && all_tags.map { |t| t["name"] }.include?(tag)
146
- idx = all_tags.index { |t| t["name"] == tag }
147
- filtered_tags = if idx > 0
148
- all_tags[(idx + 1)..-1]
149
- else
150
- []
151
- end
152
- else
153
- raise ChangelogGeneratorError, "Error: can't find tag #{tag}, specified with --due-tag option."
154
- end
136
+ return all_tags unless (tag = due_tag)
137
+
138
+ raise ChangelogGeneratorError, "Error: can't find tag #{tag}, specified with --due-tag option." if all_tags.none? { |t| t["name"] == tag }
139
+
140
+ if (idx = all_tags.index { |t| t["name"] == tag }) > 0
141
+ all_tags[(idx + 1)..]
142
+ else
143
+ []
155
144
  end
156
- filtered_tags
157
145
  end
158
146
 
159
147
  # @param [Array] all_tags all tags
@@ -207,14 +195,16 @@ module GitHubChangelogGenerator
207
195
  end
208
196
 
209
197
  def warn_if_nonmatching_regex(all_tags, regex, regex_option_name)
210
- unless all_tags.map { |t| t["name"] }.any? { |t| regex =~ t }
211
- Helper.log.warn "Warning: unable to reject any tag, using regex "\
212
- "#{regex.inspect} in #{regex_option_name} option."
213
- end
198
+ return if all_tags.any? { |t| regex.match?(t["name"]) }
199
+
200
+ Helper.log.warn "Warning: unable to reject any tag, using regex "\
201
+ "#{regex.inspect} in #{regex_option_name} option."
214
202
  end
215
203
 
216
204
  def warn_if_tag_not_found(all_tags, tag)
217
- Helper.log.warn("Warning: can't find tag #{tag}, specified with --exclude-tags option.") unless all_tags.map { |t| t["name"] }.include?(tag)
205
+ return if all_tags.any? { |t| t["name"] == tag }
206
+
207
+ Helper.log.warn("Warning: can't find tag #{tag}, specified with --exclude-tags option.")
218
208
  end
219
209
  end
220
210
  end
@@ -39,7 +39,7 @@ module GitHubChangelogGenerator
39
39
  #
40
40
  # @return [String] Generated section content
41
41
  def generate_content
42
- content = ""
42
+ content = +""
43
43
 
44
44
  if @issues.any?
45
45
  content += "#{@prefix}\n\n" unless @options[:simple_list] || @prefix.blank?
@@ -72,11 +72,11 @@ module GitHubChangelogGenerator
72
72
  end
73
73
 
74
74
  def issue_line_with_body(line, issue)
75
- return issue["body"] if @body_only && issue["body"].present?
75
+ return normalize_body(issue["body"]) if @body_only && issue["body"].present?
76
76
  return line if !@options[:issue_line_body] || issue["body"].blank?
77
77
 
78
78
  # get issue body till first line break
79
- body_paragraph = body_till_first_break(issue["body"])
79
+ body_paragraph = body_till_first_break(normalize_body(issue["body"]))
80
80
  # remove spaces from beginning of the string
81
81
  body_paragraph.rstrip!
82
82
  # encapsulate to md
@@ -85,6 +85,11 @@ module GitHubChangelogGenerator
85
85
  "**#{line}** #{encapsulated_body}"
86
86
  end
87
87
 
88
+ # Normalize line endings from CRLF to LF
89
+ def normalize_body(body)
90
+ body.gsub(/\r?\n/, "\n")
91
+ end
92
+
88
93
  def body_till_first_break(body)
89
94
  body.split(/\n/, 2).first
90
95
  end
@@ -109,7 +114,7 @@ module GitHubChangelogGenerator
109
114
  # @param [String] string
110
115
  # @return [String] encapsulated input string
111
116
  def encapsulate_string(string)
112
- string = string.gsub('\\', '\\\\')
117
+ string = string.gsub("\\", "\\\\")
113
118
 
114
119
  ENCAPSULATED_CHARACTERS.each do |char|
115
120
  # Only replace char with escaped version if it isn't inside backticks (markdown inline code).