github_changelog_generator 1.15.0.pre.rc → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +1 -1
  3. data/README.md +126 -51
  4. data/bin/git-generate-changelog +1 -1
  5. data/lib/github_changelog_generator.rb +10 -6
  6. data/lib/github_changelog_generator/generator/entry.rb +218 -0
  7. data/lib/github_changelog_generator/generator/generator.rb +96 -119
  8. data/lib/github_changelog_generator/generator/generator_fetcher.rb +140 -21
  9. data/lib/github_changelog_generator/generator/generator_processor.rb +40 -10
  10. data/lib/github_changelog_generator/generator/generator_tags.rb +10 -12
  11. data/lib/github_changelog_generator/generator/section.rb +104 -0
  12. data/lib/github_changelog_generator/octo_fetcher.rb +113 -23
  13. data/lib/github_changelog_generator/options.rb +35 -4
  14. data/lib/github_changelog_generator/parser.rb +88 -49
  15. data/lib/github_changelog_generator/parser_file.rb +6 -2
  16. data/lib/github_changelog_generator/task.rb +2 -3
  17. data/lib/github_changelog_generator/version.rb +1 -1
  18. data/man/git-generate-changelog.1 +125 -51
  19. data/man/git-generate-changelog.1.html +145 -89
  20. data/man/git-generate-changelog.html +19 -7
  21. data/man/git-generate-changelog.md +141 -86
  22. data/spec/files/github-changelog-generator.md +114 -114
  23. data/spec/{install-gem-in-bundler.gemfile → install_gem_in_bundler.gemfile} +2 -0
  24. data/spec/spec_helper.rb +1 -5
  25. data/spec/unit/generator/entry_spec.rb +760 -0
  26. data/spec/unit/generator/generator_processor_spec.rb +9 -2
  27. data/spec/unit/generator/generator_tags_spec.rb +5 -21
  28. data/spec/unit/octo_fetcher_spec.rb +204 -197
  29. data/spec/unit/options_spec.rb +24 -0
  30. data/spec/unit/parse_file_spec.rb +2 -2
  31. data/spec/unit/reader_spec.rb +4 -4
  32. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits/when_API_is_valid/returns_commits.json +1 -0
  33. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits_before/when_API_is_valid/returns_commits.json +1 -1
  34. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid.json +1 -1
  35. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issue_with_proper_key/values.json +1 -1
  36. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues.json +1 -1
  37. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues_with_labels.json +1 -1
  38. 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
  39. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_requests_with_labels.json +1 -1
  40. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid.json +1 -1
  41. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_correct_pull_request_keys.json +1 -1
  42. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_pull_requests.json +1 -1
  43. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid.json +1 -1
  44. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid/returns_commit.json +1 -1
  45. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid.json +1 -1
  46. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid/returns_date.json +1 -1
  47. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid.json +1 -1
  48. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid/populates_issues.json +1 -1
  49. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid.json +1 -1
  50. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags.json +1 -1
  51. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags_count.json +1 -1
  52. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided.json +1 -1
  53. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided/should_raise_Unauthorized_error.json +1 -1
  54. metadata +17 -17
  55. data/bin/ghclgen +0 -5
  56. data/lib/github_changelog_generator/generator/generator_generation.rb +0 -181
  57. data/spec/unit/generator/generator_generation_spec.rb +0 -73
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ec76ed478bd8c2cf2500a55c75c1a9f12ffc46d6
4
- data.tar.gz: 50192107d5f4ef52815262e08980c01a4c348781
2
+ SHA256:
3
+ metadata.gz: 7ee18824228b1ec5cade4842046046452afa0c4a0cab01ee3c52f86b60206cfb
4
+ data.tar.gz: 2c6df785e4d34d416255d1949e58a3a2668453e1a8246ae706989ddf17442bd7
5
5
  SHA512:
6
- metadata.gz: 2e40ddcaeb4205c6b44aee5ed18728eba7f6b27423055746edd39b180267d41276b86074dfc7d4c612f65f2218553a7d8fe6ccace873fbc7dd2b025f28dddad6
7
- data.tar.gz: 79270b1372d108a8645a246933219804595e88c9226202736926ab511cc0cd780e2bff5654fe32d408363a34904bd5d92e24e39aff8eda49aa7225ee961b51ec
6
+ metadata.gz: cd20b1b8916d83db50428dbe899c346d1a2b2ca1b26427fdc9997b2edf7604db530b9372c4461f443f4e7f0fc0133c6bd01b8643b1ec066cd1c80c4d0657ca3e
7
+ data.tar.gz: 41169d141f512dbecc520251f50fb9db63d4df6160621c5b8598dabf31095d9b75ae7b3aeab1bc126ac9fc5e5a71131026235bce4acb8661ed29744e6a246fa0
data/LICENSE CHANGED
@@ -1,5 +1,5 @@
1
1
  The MIT License (MIT)
2
- Copyright (c) 2016-2017 Petr Korolev
2
+ Copyright (c) 2016-2019 Petr Korolev
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
5
 
data/README.md CHANGED
@@ -1,35 +1,54 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/github_changelog_generator.svg)](http://badge.fury.io/rb/github_changelog_generator)
2
- [![Dependency Status](https://gemnasium.com/skywinder/github-changelog-generator.svg)](https://gemnasium.com/skywinder/github-changelog-generator)
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)
5
- [![Inline docs](http://inch-ci.org/github/skywinder/github-changelog-generator.svg)](http://inch-ci.org/github/skywinder/github-changelog-generator)
6
- [![Code Climate](https://codeclimate.com/github/skywinder/github-changelog-generator/badges/gpa.svg)](https://codeclimate.com/github/skywinder/github-changelog-generator)
7
- [![Test Coverage](https://codeclimate.com/github/skywinder/github-changelog-generator/badges/coverage.svg)](https://codeclimate.com/github/skywinder/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)
8
4
  [![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)
9
5
 
10
- GitHub Changelog Generator ![GitHub Logo](../master/images/logo.jpg)
11
- ==================
12
-
13
- - [Installation](#installation)
14
- - [Output example](#output-example)
15
- - [Usage](#usage)
16
- - [Params](#params)
17
- - [GitHub token](#github-token)
18
- - [Features and advantages of this project](#features-and-advantages-of-this-project)
19
- - [Alternatives](#alternatives)
20
- - [Projects using this library](#projects-using-this-library)
21
- - [Am I missing some essential feature?](#am-i-missing-some-essential-feature)
22
- - [Contributing](#contributing)
23
- - [License](#license)
6
+ # github-changelog-generator ![GitHub Logo](../master/images/logo.jpg)
7
+
8
+ #### Update:
9
+
10
+ 🖖 Keep it alive: We need more Collaborators to github-changelog-generator [#727](https://github.com/github-changelog-generator/github-changelog-generator/issues/727)
11
+
12
+ ---
13
+ <!--
14
+ To update TOC, please run:
15
+ > doctoc ./README.md --github
16
+ -->
17
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
18
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
19
+
20
+
21
+ - [Changelog generation has never been so easy](#changelog-generation-has-never-been-so-easy)
22
+ - [*What’s the point of a changelog?*](#whats-the-point-of-a-changelog)
23
+ - [*Why should I care?*](#why-should-i-care)
24
+ - [Installation](#installation)
25
+ - [Running with Docker](#running-with-docker)
26
+ - [Output example](#output-example)
27
+ - [Usage](#usage)
28
+ - [Params](#params)
29
+ - [Params File](#params-file)
30
+ - [GitHub token](#github-token)
31
+ - [Migrating from a manual changelog](#migrating-from-a-manual-changelog)
32
+ - [Rake task](#rake-task)
33
+ - [Features and advantages of this project](#features-and-advantages-of-this-project)
34
+ - [Using the summary section feature](#using-the-summary-section-feature)
35
+ - [Alternatives](#alternatives)
36
+ - [Projects using this library](#projects-using-this-library)
37
+ - [Am I missing some essential feature?](#am-i-missing-some-essential-feature)
38
+ - [FAQ](#faq)
39
+ - [Contributing](#contributing)
40
+ - [License](#license)
41
+
42
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
24
43
 
25
44
 
26
45
  ### Changelog generation has never been so easy
27
46
 
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.
47
+ **Fully automated changelog generation** - This gem generates a changelog file based on **tags**, **issues** and merged **pull requests** (and splits them into separate lists according to labels) from :octocat: GitHub Issue Tracker.
29
48
 
30
49
  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:
31
50
 
32
- ### *What’s the point of a change log?*
51
+ ### *What’s the point of a changelog?*
33
52
 
34
53
  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.
35
54
 
@@ -39,61 +58,83 @@ Because software tools are for _people_. "Changelogs make it easier for users an
39
58
  contributors to see precisely what notable changes have been made between each
40
59
  release (or version) of the project."
41
60
 
42
- :arrow_right: *[http://keepachangelog.com](http://keepachangelog.com)*
61
+ :arrow_right: *[https://keepachangelog.com](https://keepachangelog.com)*
43
62
 
44
63
  ## Installation
45
64
 
46
- gem install github_changelog_generator
65
+ GitHub Changelog Generator is a [Ruby](https://www.ruby-lang.org/)
66
+ program, distributed as a RubyGem. The Ruby language homepage has an [Installation page](https://www.ruby-lang.org/en/documentation/installation/).
67
+
68
+ Install the gem like:
69
+
70
+ $ gem install github_changelog_generator
71
+
72
+ Depending on your system, you _may_ need to run the shell as an Administrator (Windows),
73
+ or use `sudo gem install github_changelog_generator` (Linux).
74
+
75
+ ## Running with Docker
76
+
77
+ Using [Docker](https://www.docker.com/products/docker-desktop) is an alternative to installing Ruby and the gem.
78
+
79
+ `ferrarimarco` has made a Docker image available that you can use.
47
80
 
48
- See also Troubleshooting.
81
+ Example invocation:
82
+
83
+ $ docker run -it --rm -v "$(pwd)":/usr/local/src/your-app ferrarimarco/github-changelog-generator
49
84
 
50
85
  ## Output example
51
86
 
52
- - Look at **[CHANGELOG.md](https://github.com/skywinder/Github-Changelog-Generator/blob/master/CHANGELOG.md)** for this project
53
- - [ActionSheetPicker-3.0/CHANGELOG.md](https://github.com/skywinder/ActionSheetPicker-3.0/blob/master/CHANGELOG.md) was generated by command:
87
+ - Look at **[CHANGELOG.md](https://github.com/github-changelog-generator/Github-Changelog-Generator/blob/master/CHANGELOG.md)** for this project
88
+ - [ActionSheetPicker-3.0/CHANGELOG.md](https://github.com/skywinder/ActionSheetPicker-3.0/blob/develop/CHANGELOG.md) was generated by command:
54
89
 
55
- github_changelog_generator -u skywinder -p ActionSheetPicker-3.0
90
+ $ github_changelog_generator -u github-changelog-generator -p ActionSheetPicker-3.0
56
91
 
57
92
  - In general, it looks like this:
58
93
 
59
- > ## [1.2.5](https://github.com/skywinder/Github-Changelog-Generator/tree/1.2.5) (2015-01-15)
94
+ > ## [1.2.5](https://github.com/github-changelog-generator/Github-Changelog-Generator/tree/1.2.5) (2015-01-15)
60
95
  >
61
- > [Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.2.4...1.2.5)
96
+ > [Full Changelog](https://github.com/github-changelog-generator/Github-Changelog-Generator/compare/1.2.4...1.2.5)
62
97
  >
63
98
  > **Implemented enhancements:**
64
99
  >
65
- > - Use milestone to specify in which version bug was fixed [\#22](https://github.com/skywinder/Github-Changelog-Generator/issues/22)
100
+ > - Use milestone to specify in which version bug was fixed [\#22](https://github.com/github-changelog-generator/Github-Changelog-Generator/issues/22)
66
101
  >
67
102
  > **Fixed bugs:**
68
103
  >
69
- > - Error when trying to generate log for repo without tags [\#32](https://github.com/skywinder/Github-Changelog-Generator/issues/32)
104
+ > - Error when trying to generate log for repo without tags [\#32](https://github.com/github-changelog-generator/Github-Changelog-Generator/issues/32)
70
105
  >
71
106
  > **Merged pull requests:**
72
107
  >
73
- > - PrettyPrint class is included using lowercase 'pp' [\#43](https://github.com/skywinder/Github-Changelog-Generator/pull/43) ([schwing](https://github.com/schwing))
108
+ > - PrettyPrint class is included using lowercase 'pp' [\#43](https://github.com/github-changelog-generator/Github-Changelog-Generator/pull/43) ([schwing](https://github.com/schwing))
74
109
  >
75
- > - support enterprise github via command line options [\#42](https://github.com/skywinder/Github-Changelog-Generator/pull/42) ([glenlovett](https://github.com/glenlovett))
110
+ > - support enterprise github via command line options [\#42](https://github.com/github-changelog-generator/Github-Changelog-Generator/pull/42) ([glenlovett](https://github.com/glenlovett))
76
111
 
77
112
 
78
113
  ## Usage
79
114
 
80
115
  - Run this:
81
116
 
82
- `github_changelog_generator -u github_username -p github_project`
83
- `github_changelog_generator github_username/github_project`
117
+ $ github_changelog_generator -u github_username -p github_project
118
+
119
+ or, on the 1.14.x (current stable release)
120
+
121
+ $ github_changelog_generator github_username/github_project
122
+
84
123
 
85
124
  - For Github Enterprise repos, specify *both* `--github-site` and `--github-api` options:
86
125
 
87
- github_changelog_generator --github-site="https://github.yoursite.com" \
88
- --github-api="https://github.yoursite.com/api/v3/"
126
+ $ github_changelog_generator --github-site="https://github.yoursite.com" \
127
+ --github-api="https://github.yoursite.com/api/v3/"
89
128
 
90
129
  This generates a `CHANGELOG.md`, with pretty Markdown formatting.
91
130
 
92
131
  ### Params
93
132
 
94
- Type `github_changelog_generator --help` for details.
133
+ Print help for all command-line options to learn more details:
134
+
135
+ $ github_changelog_generator --help
95
136
 
96
- For more details about params, read the Wiki page: [**Advanced change log generation examples**](https://github.com/skywinder/github-changelog-generator/wiki/Advanced-change-log-generation-examples)
137
+ For more details about params, read the Wiki page: [**Advanced changelog generation examples**](https://github.com/github-changelog-generator/github-changelog-generator/wiki/Advanced-change-log-generation-examples)
97
138
 
98
139
  ### Params File
99
140
 
@@ -154,6 +195,8 @@ Configure the task in your `Rakefile`:
154
195
  require 'github_changelog_generator/task'
155
196
 
156
197
  GitHubChangelogGenerator::RakeTask.new :changelog do |config|
198
+ config.user = 'username'
199
+ config.project = 'project-name'
157
200
  config.since_tag = '0.1.14'
158
201
  config.future_release = '0.2.0'
159
202
  end
@@ -163,11 +206,11 @@ All command-line options can be passed to the `rake` task as `config`
163
206
  parameters. And since you're naming the `rake` task yourself, you can create
164
207
  as many as you want.
165
208
 
166
- You can look for params names from the [parser source code (#setup_parser)](https://github.com/skywinder/github-changelog-generator/blob/master/lib/github_changelog_generator/parser.rb). For example, to translate the bugs label to Portuguese, instead of setting `config.bugs_label`, you have to set `config.bug_prefix`, and so on.
209
+ You can look for params names from the [parser source code (#setup_parser)](https://github.com/github-changelog-generator/github-changelog-generator/blob/master/lib/github_changelog_generator/parser.rb). For example, to translate the bugs label to Portuguese, instead of setting `config.bugs_label`, you have to set `config.bug_prefix`, and so on.
167
210
 
168
211
  ## Features and advantages of this project
169
212
 
170
- - Generate canonical, neat change log file, followed by [basic change log guidelines](http://keepachangelog.com) :gem:
213
+ - Generate canonical, neat changelog file, with default sections that follow [basic changelog guidelines](http://keepachangelog.com) :gem:
171
214
  - Optionally generate **Unreleased** changes (closed issues that have not released yet) :dizzy:
172
215
  - **GitHub Enterprise support** via command line options! :factory:
173
216
  - Flexible format **customization**:
@@ -185,27 +228,53 @@ You can look for params names from the [parser source code (#setup_parser)](http
185
228
  - Customize lots more! Tweak the changelog to fit your preferences :tophat:
186
229
  (*See `github_changelog_generator --help` for details)*
187
230
 
231
+ ### Using the summary section feature
232
+
233
+ For each version, you can add a _release summary_ with text, images, gif animations,
234
+ etc, and show new features and notes clearly to the user. This is done using GitHub metadata.
235
+
236
+ **Example**: adding the release summary for v1.0.0:
237
+
238
+ 1. Create a new GitHub Issue
239
+ 2. In the Issue's _Description_ field, add your release summary content
240
+ ```
241
+ ![image](https://user-images.githubusercontent.com/12690315/45935880-006a8200-bfeb-11e8-958e-ff742ae66b96.png)
242
+
243
+ Hello, World! :tada:
244
+ ```
245
+ 3. Set the Issue Label `release-summary` and add it to the GitHub Milestone `v1.0.0`
246
+ 4. Close the Issue and execute `github-changelog-generator`
247
+ 5. The result looks like this:
248
+ > ## [v1.0.0](https://github.com/github-changelog-generator/github-changelog-generator/tree/1.0.0) (2014-11-07)
249
+ > [Full Changelog](https://github.com/github-changelog-generator/github-changelog-generator/compare/0.1.0...1.0.0)
250
+ >
251
+ > ![image](https://user-images.githubusercontent.com/12690315/45935880-006a8200-bfeb-11e8-958e-ff742ae66b96.png)
252
+ >
253
+ > Hello, World! :tada:
254
+ >
255
+ > **Implemented enhancements:**
256
+ > - Add some features
188
257
 
189
258
  ### Alternatives
190
259
 
191
- Here is a [wikipage list of alternatives](https://github.com/skywinder/Github-Changelog-Generator/wiki/Alternatives) that I found. But none satisfied my requirements.
260
+ 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.
192
261
 
193
262
  *If you know other projects, feel free to edit this Wiki page!*
194
263
 
195
264
 
196
265
  ### Projects using this library
197
266
 
198
- Here's a [wikipage list of projects](https://github.com/skywinder/Github-Changelog-Generator/wiki/Projects-using-Github-Changelog-Generator).
267
+ Here's a [wikipage list of projects](https://github.com/github-changelog-generator/Github-Changelog-Generator/wiki/Projects-using-Github-Changelog-Generator).
199
268
 
200
269
  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.
201
270
 
202
- *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/skywinder/github-changelog-generator/wiki/Projects-using-Github-Changelog-Generator).*
271
+ *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).*
203
272
 
204
273
  ## Am I missing some essential feature?
205
274
 
206
275
  - **Nothing is impossible!**
207
276
 
208
- - Open an [issue](https://github.com/skywinder/Github-Changelog-Generator/issues/new) and let's make the generator better together!
277
+ - Open an [issue](https://github.com/github-changelog-generator/Github-Changelog-Generator/issues/new) and let's make the generator better together!
209
278
 
210
279
  - *Bug reports, feature requests, patches, and well-wishes are always welcome.* :heavy_exclamation_mark:
211
280
 
@@ -215,7 +284,7 @@ If you've used this project in a live app, please let me know! Nothing makes me
215
284
 
216
285
  GitHub Releases is a very good thing. And it's very good practice to maintain it. (Not a lot of people are using it yet!) :congratulations:
217
286
 
218
- *BTW: I would like to support GitHub Releases in [next releases](https://github.com/skywinder/github-changelog-generator/issues/56) ;)*
287
+ *BTW: I would like to support GitHub Releases in [next releases](https://github.com/github-changelog-generator/github-changelog-generator/issues/56) ;)*
219
288
 
220
289
  I'm not trying to compare the quality of handwritten and auto-generated logs. That said....
221
290
 
@@ -226,15 +295,15 @@ For example:
226
295
  When you find a closed bug, it is very useful to know which release fixed it.
227
296
  So that you can easily find the issue by \# in `CHANGELOG.md`.
228
297
 
229
- - it's not quite as easy to find this in handwritten releases notes
230
- - a generated file saves you the trouble of remembering everything;
231
- sometimes people forget to add things to a handwritten file
298
+ - It's not quite as easy to find this in handwritten releases notes.
299
+ - A generated file saves you the trouble of remembering everything;
300
+ sometimes people forget to add things to a handwritten file.
232
301
 
233
302
  Ultimately, I think GitHub Releases are ideal for end-users.
234
303
  Meanwhile, `CHANGELOG.md` lives right in the repository, with its detailed list of changes, which is handy for developers.
235
304
  Finally, there's nothing wrong with using GitHub Releases alongside `CHANGELOG.md` in this combination.
236
305
 
237
- - ***I received a warning: "GitHub API rate limit exceed" What does this mean?***
306
+ - ***I got an "API rate limit exceeded" error message. What does this mean?***
238
307
 
239
308
  GitHub [limits the number of API requests](https://developer.github.com/v3/#rate-limiting) you can make in an hour. You can make up to 5,000 requests per hour. For unauthenticated requests, the rate limit is only up to 60 requests per hour. Unauthenticated requests are associated with your IP address (not the user making requests).
240
309
 
@@ -268,6 +337,12 @@ gem 'rack', '~> 1.6'
268
337
  This way, you can keep on using github_changelog_generator, even if you
269
338
  can't get the latest version of Ruby installed.
270
339
 
340
+ - ***Windows: 1.14.x wants to create a file on an invalid path. Why?***
341
+
342
+ Windows: [v1.14.0 introduced a bug where it attempts to create /tmp/github_changelog-logger.log... which isn't a valid path on Windows and thus fails](https://github.com/github-changelog-generator/github-changelog-generator/issues/458)
343
+
344
+ Workaround: Create a `C:\tmp`.
345
+
271
346
  ## Contributing
272
347
 
273
348
  We have collected notes on how to contribute to this project in [CONTRIBUTING.md].
@@ -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"
@@ -22,22 +22,26 @@ require "github_changelog_generator/reader"
22
22
  module GitHubChangelogGenerator
23
23
  # Main class and entry point for this script.
24
24
  class ChangelogGenerator
25
- # Class, responsible for whole change log generation cycle
25
+ # Class, responsible for whole changelog generation cycle
26
26
  # @return initialised instance of ChangelogGenerator
27
27
  def initialize
28
28
  @options = Parser.parse_options
29
29
  @generator = Generator.new @options
30
30
  end
31
31
 
32
- # The entry point of this script to generate change log
32
+ # The entry point of this script to generate changelog
33
33
  # @raise (ChangelogGeneratorError) Is thrown when one of specified tags was not found in list of tags.
34
34
  def run
35
35
  log = @generator.compound_changelog
36
36
 
37
- output_filename = @options[:output].to_s
38
- File.open(output_filename, "wb") { |file| file.write(log) }
39
- puts "Done!"
40
- puts "Generated log placed in #{Dir.pwd}/#{output_filename}"
37
+ if @options.write_to_file?
38
+ output_filename = @options[:output].to_s
39
+ File.open(output_filename, "wb") { |file| file.write(log) }
40
+ puts "Done!"
41
+ puts "Generated log placed in #{Dir.pwd}/#{output_filename}"
42
+ else
43
+ puts log
44
+ end
41
45
  end
42
46
  end
43
47
  end
@@ -0,0 +1,218 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "github_changelog_generator/generator/section"
4
+
5
+ module GitHubChangelogGenerator
6
+ # This class generates the content for a single changelog entry. An entry is
7
+ # generally either for a specific tagged release or the collection of
8
+ # unreleased changes.
9
+ #
10
+ # An entry is comprised of header text followed by a series of sections
11
+ # relating to the entry.
12
+ #
13
+ # @see GitHubChangelogGenerator::Generator
14
+ # @see GitHubChangelogGenerator::Section
15
+ class Entry
16
+ attr_reader :content
17
+
18
+ def initialize(options = Options.new({}))
19
+ @content = ""
20
+ @options = Options.new(options)
21
+ end
22
+
23
+ # Generates log entry with header and body
24
+ #
25
+ # @param [Array] pull_requests List or PR's in new section
26
+ # @param [Array] issues List of issues in new section
27
+ # @param [String] newer_tag_name Name of the newer tag. Could be nil for `Unreleased` section.
28
+ # @param [String] newer_tag_link Name of the newer tag. Could be "HEAD" for `Unreleased` section.
29
+ # @param [Time] newer_tag_time Time of the newer tag
30
+ # @param [Hash, nil] older_tag_name Older tag, used for the links. Could be nil for last tag.
31
+ # @return [String] Ready and parsed section content.
32
+ def generate_entry_for_tag(pull_requests, issues, newer_tag_name, newer_tag_link, newer_tag_time, older_tag_name) # rubocop:disable Metrics/ParameterLists
33
+ github_site = @options[:github_site] || "https://github.com"
34
+ project_url = "#{github_site}/#{@options[:user]}/#{@options[:project]}"
35
+
36
+ create_sections
37
+
38
+ @content = generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_name, project_url)
39
+ @content += generate_body(pull_requests, issues)
40
+ @content
41
+ end
42
+
43
+ private
44
+
45
+ # Creates section objects for this entry.
46
+ # @return [Nil]
47
+ def create_sections
48
+ @sections = if @options.configure_sections?
49
+ parse_sections(@options[:configure_sections])
50
+ elsif @options.add_sections?
51
+ default_sections.concat parse_sections(@options[:add_sections])
52
+ else
53
+ default_sections
54
+ end
55
+ nil
56
+ end
57
+
58
+ # Turns the argument from the commandline of --configure-sections or
59
+ # --add-sections into an array of Section objects.
60
+ #
61
+ # @param [String, Hash] sections_desc Either string or hash describing sections
62
+ # @return [Array] Parsed section objects.
63
+ def parse_sections(sections_desc)
64
+ require "json"
65
+
66
+ sections_desc = sections_desc.to_json if sections_desc.class == Hash
67
+
68
+ begin
69
+ sections_json = JSON.parse(sections_desc)
70
+ rescue JSON::ParserError => e
71
+ raise "There was a problem parsing your JSON string for sections: #{e}"
72
+ end
73
+
74
+ sections_json.collect do |name, v|
75
+ Section.new(name: name.to_s, prefix: v["prefix"], labels: v["labels"], options: @options)
76
+ end
77
+ end
78
+
79
+ # Generates header text for an entry.
80
+ #
81
+ # @param [String] newer_tag_name The name of a newer tag
82
+ # @param [String] newer_tag_link Used for URL generation. Could be same as #newer_tag_name or some specific value, like HEAD
83
+ # @param [Time] newer_tag_time Time when the newer tag was created
84
+ # @param [String] older_tag_name The name of an older tag; used for URLs.
85
+ # @param [String] project_url URL for the current project.
86
+ # @return [String] Header text content.
87
+ def generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_name, project_url)
88
+ header = ""
89
+
90
+ # Generate date string:
91
+ time_string = newer_tag_time.strftime(@options[:date_format])
92
+
93
+ # Generate tag name and link
94
+ release_url = if @options[:release_url]
95
+ format(@options[:release_url], newer_tag_link)
96
+ else
97
+ "#{project_url}/tree/#{newer_tag_link}"
98
+ end
99
+ header += if newer_tag_name.equal?(@options[:unreleased_label])
100
+ "## [#{newer_tag_name}](#{release_url})\n\n"
101
+ else
102
+ "## [#{newer_tag_name}](#{release_url}) (#{time_string})\n\n"
103
+ end
104
+
105
+ if @options[:compare_link] && older_tag_name
106
+ # Generate compare link
107
+ header += "[Full Changelog](#{project_url}/compare/#{older_tag_name}...#{newer_tag_link})\n\n"
108
+ end
109
+
110
+ header
111
+ end
112
+
113
+ # Generates complete body text for a tag (without a header)
114
+ #
115
+ # @param [Array] pull_requests
116
+ # @param [Array] issues
117
+ # @return [String] Content generated from sections of sorted issues & PRs.
118
+ def generate_body(pull_requests, issues)
119
+ sort_into_sections(pull_requests, issues)
120
+ @sections.map(&:generate_content).join
121
+ end
122
+
123
+ # Default sections to used when --configure-sections is not set.
124
+ #
125
+ # @return [Array] Section objects.
126
+ def default_sections
127
+ [
128
+ Section.new(name: "summary", prefix: @options[:summary_prefix], labels: @options[:summary_labels], options: @options, body_only: true),
129
+ Section.new(name: "breaking", prefix: @options[:breaking_prefix], labels: @options[:breaking_labels], options: @options),
130
+ Section.new(name: "enhancements", prefix: @options[:enhancement_prefix], labels: @options[:enhancement_labels], options: @options),
131
+ Section.new(name: "bugs", prefix: @options[:bug_prefix], labels: @options[:bug_labels], options: @options),
132
+ Section.new(name: "deprecated", prefix: @options[:deprecated_prefix], labels: @options[:deprecated_labels], options: @options),
133
+ Section.new(name: "removed", prefix: @options[:removed_prefix], labels: @options[:removed_labels], options: @options),
134
+ Section.new(name: "security", prefix: @options[:security_prefix], labels: @options[:security_labels], options: @options)
135
+ ]
136
+ end
137
+
138
+ # Sorts issues and PRs into entry sections by labels and lack of labels.
139
+ #
140
+ # @param [Array] pull_requests
141
+ # @param [Array] issues
142
+ # @return [Nil]
143
+ def sort_into_sections(pull_requests, issues)
144
+ if @options[:issues]
145
+ unmapped_issues = sort_labeled_issues(issues)
146
+ add_unmapped_section(unmapped_issues)
147
+ end
148
+ if @options[:pulls]
149
+ unmapped_pull_requests = sort_labeled_issues(pull_requests)
150
+ add_unmapped_section(unmapped_pull_requests)
151
+ end
152
+ nil
153
+ end
154
+
155
+ # Iterates through sections and sorts labeled issues into them based on
156
+ # the label mapping. Returns any unmapped or unlabeled issues.
157
+ #
158
+ # @param [Array] issues Issues or pull requests.
159
+ # @return [Array] Issues that were not mapped into any sections.
160
+ def sort_labeled_issues(issues)
161
+ sorted_issues = []
162
+ issues.each do |issue|
163
+ label_names = issue["labels"].collect { |l| l["name"] }
164
+
165
+ # Add PRs in the order of the @sections array. This will either be the
166
+ # default sections followed by any --add-sections sections in
167
+ # user-defined order, or --configure-sections in user-defined order.
168
+ # Ignore the order of the issue labels from github which cannot be
169
+ # controled by the user.
170
+ @sections.each do |section|
171
+ unless (section.labels & label_names).empty?
172
+ section.issues << issue
173
+ sorted_issues << issue
174
+ break
175
+ end
176
+ end
177
+ end
178
+ issues - sorted_issues
179
+ end
180
+
181
+ # Creates a section for issues/PRs with no labels or no mapped labels.
182
+ #
183
+ # @param [Array] issues
184
+ # @return [Nil]
185
+ def add_unmapped_section(issues)
186
+ unless issues.empty?
187
+ # Distinguish between issues and pull requests
188
+ if issues.first.key?("pull_request")
189
+ name = "merged"
190
+ prefix = @options[:merge_prefix]
191
+ add_wo_labels = @options[:add_pr_wo_labels]
192
+ else
193
+ name = "issues"
194
+ prefix = @options[:issue_prefix]
195
+ add_wo_labels = @options[:add_issues_wo_labels]
196
+ end
197
+ add_issues = if add_wo_labels
198
+ issues
199
+ else
200
+ # Only add unmapped issues
201
+ issues.select { |issue| issue["labels"].any? }
202
+ end
203
+ merged = Section.new(name: name, prefix: prefix, labels: [], issues: add_issues, options: @options) unless add_issues.empty?
204
+ @sections << merged
205
+ end
206
+ nil
207
+ end
208
+
209
+ def line_labels_for(issue)
210
+ labels = if @options[:issue_line_labels] == ["ALL"]
211
+ issue["labels"]
212
+ else
213
+ issue["labels"].select { |label| @options[:issue_line_labels].include?(label["name"]) }
214
+ end
215
+ labels.map { |label| " \[[#{label['name']}](#{label['url'].sub('api.github.com/repos', 'github.com')})\]" }.join("")
216
+ end
217
+ end
218
+ end