github_changelog_generator 1.15.0.pre.rc → 1.16.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +1 -1
  3. data/README.md +134 -81
  4. data/Rakefile +1 -1
  5. data/bin/git-generate-changelog +1 -1
  6. data/lib/github_changelog_generator.rb +10 -6
  7. data/lib/github_changelog_generator/argv_parser.rb +224 -0
  8. data/lib/github_changelog_generator/generator/entry.rb +218 -0
  9. data/lib/github_changelog_generator/generator/generator.rb +120 -121
  10. data/lib/github_changelog_generator/generator/generator_fetcher.rb +138 -23
  11. data/lib/github_changelog_generator/generator/generator_processor.rb +60 -27
  12. data/lib/github_changelog_generator/generator/generator_tags.rb +25 -21
  13. data/lib/github_changelog_generator/generator/section.rb +124 -0
  14. data/lib/github_changelog_generator/helper.rb +1 -1
  15. data/lib/github_changelog_generator/octo_fetcher.rb +250 -96
  16. data/lib/github_changelog_generator/options.rb +39 -4
  17. data/lib/github_changelog_generator/parser.rb +70 -209
  18. data/lib/github_changelog_generator/parser_file.rb +35 -16
  19. data/lib/github_changelog_generator/reader.rb +2 -2
  20. data/lib/github_changelog_generator/ssl_certs/cacert.pem +851 -1680
  21. data/lib/github_changelog_generator/task.rb +4 -4
  22. data/lib/github_changelog_generator/version.rb +1 -1
  23. data/man/git-generate-changelog.1 +160 -74
  24. data/man/git-generate-changelog.1.html +159 -95
  25. data/man/git-generate-changelog.html +36 -24
  26. data/man/git-generate-changelog.md +156 -93
  27. data/spec/files/config_example +5 -0
  28. data/spec/files/github-changelog-generator.md +114 -114
  29. data/spec/{install-gem-in-bundler.gemfile → install_gem_in_bundler.gemfile} +2 -0
  30. data/spec/spec_helper.rb +2 -6
  31. data/spec/unit/generator/entry_spec.rb +766 -0
  32. data/spec/unit/generator/generator_processor_spec.rb +103 -41
  33. data/spec/unit/generator/generator_spec.rb +47 -0
  34. data/spec/unit/generator/generator_tags_spec.rb +51 -24
  35. data/spec/unit/generator/section_spec.rb +34 -0
  36. data/spec/unit/octo_fetcher_spec.rb +247 -197
  37. data/spec/unit/options_spec.rb +24 -0
  38. data/spec/unit/parse_file_spec.rb +2 -2
  39. data/spec/unit/parser_spec.rb +50 -0
  40. data/spec/unit/reader_spec.rb +4 -4
  41. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits/when_API_is_valid/returns_commits.json +1 -0
  42. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits_before/when_API_is_valid/returns_commits.json +1 -1
  43. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid.json +1 -1
  44. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issue_with_proper_key/values.json +1 -1
  45. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues.json +1 -1
  46. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues_with_labels.json +1 -1
  47. 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
  48. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_requests_with_labels.json +1 -1
  49. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid.json +1 -1
  50. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_correct_pull_request_keys.json +1 -1
  51. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_pull_requests.json +1 -1
  52. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid.json +1 -1
  53. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid/returns_commit.json +1 -1
  54. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid.json +1 -1
  55. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid/returns_date.json +1 -1
  56. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid.json +1 -1
  57. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid/populates_issues.json +1 -1
  58. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid.json +1 -1
  59. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags.json +1 -1
  60. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags_count.json +1 -1
  61. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided.json +1 -1
  62. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided/should_raise_Unauthorized_error.json +1 -1
  63. metadata +56 -20
  64. data/bin/ghclgen +0 -5
  65. data/lib/github_changelog_generator/generator/generator_generation.rb +0 -181
  66. data/spec/unit/generator/generator_generation_spec.rb +0 -73
@@ -7,7 +7,7 @@ module GitHubChangelogGenerator
7
7
  # This class wraps Options, and knows a list of known options. Others options
8
8
  # will raise exceptions.
9
9
  class Options < SimpleDelegator
10
- # Raised on intializing with unknown keys in the values hash,
10
+ # Raised on initializing with unknown keys in the values hash,
11
11
  # and when trying to store a value on an unknown key.
12
12
  UnsupportedOptionError = Class.new(ArgumentError)
13
13
 
@@ -15,24 +15,30 @@ module GitHubChangelogGenerator
15
15
  KNOWN_OPTIONS = %i[
16
16
  add_issues_wo_labels
17
17
  add_pr_wo_labels
18
+ add_sections
18
19
  author
19
20
  base
20
21
  between_tags
22
+ breaking_labels
23
+ breaking_prefix
21
24
  bug_labels
22
25
  bug_prefix
23
26
  cache_file
24
27
  cache_log
28
+ config_file
25
29
  compare_link
30
+ configure_sections
26
31
  date_format
32
+ deprecated_labels
33
+ deprecated_prefix
27
34
  due_tag
28
35
  enhancement_labels
29
36
  enhancement_prefix
30
- breaking_labels
31
- breaking_prefix
32
37
  exclude_labels
33
38
  exclude_tags
34
39
  exclude_tags_regex
35
40
  filter_issues_by_milestone
41
+ issues_of_open_milestones
36
42
  frontmatter
37
43
  future_release
38
44
  github_endpoint
@@ -40,8 +46,10 @@ module GitHubChangelogGenerator
40
46
  header
41
47
  http_cache
42
48
  include_labels
49
+ include_tags_regex
43
50
  issue_prefix
44
51
  issue_line_labels
52
+ issue_line_body
45
53
  issues
46
54
  max_issues
47
55
  merge_prefix
@@ -50,10 +58,17 @@ module GitHubChangelogGenerator
50
58
  pulls
51
59
  release_branch
52
60
  release_url
61
+ removed_labels
62
+ removed_prefix
53
63
  require
64
+ security_labels
65
+ security_prefix
54
66
  simple_list
55
67
  since_tag
68
+ since_commit
56
69
  ssl_ca_file
70
+ summary_labels
71
+ summary_prefix
57
72
  token
58
73
  unreleased
59
74
  unreleased_label
@@ -95,11 +110,31 @@ module GitHubChangelogGenerator
95
110
  # Pretty-prints a censored options hash, if :verbose.
96
111
  def print_options
97
112
  return unless self[:verbose]
113
+
98
114
  Helper.log.info "Using these options:"
99
- pp(censored_values)
115
+ # For ruby 2.5.0+
116
+ censored_values.each do |key, value|
117
+ print(key.inspect, "=>", value.inspect)
118
+ puts ""
119
+ end
100
120
  puts ""
101
121
  end
102
122
 
123
+ # Boolean method for whether the user is using configure_sections
124
+ def configure_sections?
125
+ !self[:configure_sections].nil? && !self[:configure_sections].empty?
126
+ end
127
+
128
+ # Boolean method for whether the user is using add_sections
129
+ def add_sections?
130
+ !self[:add_sections].nil? && !self[:add_sections].empty?
131
+ end
132
+
133
+ # @return [Boolean] whether write to `:output`
134
+ def write_to_file?
135
+ self[:output].present?
136
+ end
137
+
103
138
  private
104
139
 
105
140
  def values
@@ -1,228 +1,89 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require "optparse"
5
- require "pp"
6
- require "github_changelog_generator/version"
7
4
  require "github_changelog_generator/helper"
5
+ require "github_changelog_generator/argv_parser"
6
+ require "github_changelog_generator/parser_file"
8
7
 
9
8
  module GitHubChangelogGenerator
10
9
  class Parser
11
- # parse options with optparse
12
- def self.parse_options
13
- options = default_options
10
+ class << self
11
+ PARSERS = [
12
+ ArgvParser, # Parse arguments first to get initial options populated
13
+ FileParserChooser, # Then parse possible configuration files
14
+ ArgvParser # Lastly parse arguments again to keep the given arguments the strongest
15
+ ].freeze
14
16
 
15
- ParserFile.new(options).parse!
17
+ def parse_options(argv = ARGV)
18
+ options = default_options
16
19
 
17
- parser = setup_parser(options)
18
- begin parser.parse!
19
- rescue OptionParser::InvalidOption => e
20
- abort [e, parser].join("\n")
21
- end
20
+ PARSERS.each do |parser|
21
+ parser.new(options).parse!(argv)
22
+ end
22
23
 
23
- unless options[:user] && options[:project]
24
- warn "Configure which user and project to work on."
25
- warn "Options --user and --project, or settings to that effect. See --help for more."
26
- abort(parser.banner)
24
+ abort_if_user_and_project_not_given!(options)
25
+
26
+ options.print_options
27
+
28
+ options
27
29
  end
28
30
 
29
- options.print_options
31
+ def abort_if_user_and_project_not_given!(options)
32
+ return if options[:user] && options[:project]
30
33
 
31
- options
32
- end
34
+ warn "Configure which user and project to work on."
35
+ warn "Options --user and --project, or settings to that effect. See --help for more."
36
+ warn ArgvParser.banner
33
37
 
34
- # Setup parsing options
35
- #
36
- # @param options [Options]
37
- # @return [OptionParser]
38
- def self.setup_parser(options)
39
- OptionParser.new do |opts| # rubocop:disable Metrics/BlockLength
40
- opts.banner = "Usage: github_changelog_generator --user USER --project PROJECT [options]"
41
- opts.on("-u", "--user USER", "Username of the owner of target GitHub repo") do |last|
42
- options[:user] = last
43
- end
44
- opts.on("-p", "--project PROJECT", "Name of project on GitHub") do |last|
45
- options[:project] = last
46
- end
47
- opts.on("-t", "--token [TOKEN]", "To make more than 50 requests per hour your GitHub token is required. You can generate it at: https://github.com/settings/tokens/new") do |last|
48
- options[:token] = last
49
- end
50
- opts.on("-f", "--date-format FORMAT", "Date format. Default is %Y-%m-%d") do |last|
51
- options[:date_format] = last
52
- end
53
- opts.on("-o", "--output [NAME]", "Output file. Default is CHANGELOG.md") do |last|
54
- options[:output] = last
55
- end
56
- opts.on("-b", "--base [NAME]", "Optional base file to append generated changes to.") do |last|
57
- options[:base] = last
58
- end
59
- opts.on("--bugs-label [LABEL]", "Setup custom label for bug-fixes section. Default is \"**Fixed bugs:**\"") do |v|
60
- options[:bug_prefix] = v
61
- end
62
- opts.on("--enhancement-label [LABEL]", "Setup custom label for enhancements section. Default is \"**Implemented enhancements:**\"") do |v|
63
- options[:enhancement_prefix] = v
64
- end
65
- opts.on("--breaking-label [LABEL]", "Setup custom label for the breaking changes section. Default is \"**Breaking changes:**\"") do |v|
66
- options[:breaking_prefix] = v
67
- end
68
- opts.on("--issues-label [LABEL]", "Setup custom label for closed-issues section. Default is \"**Closed issues:**\"") do |v|
69
- options[:issue_prefix] = v
70
- end
71
- opts.on("--header-label [LABEL]", "Setup custom header label. Default is \"# Change Log\"") do |v|
72
- options[:header] = v
73
- end
74
- opts.on("--front-matter [JSON]", "Add YAML front matter. Formatted as JSON because it's easier to add on the command line") do |v|
75
- options[:frontmatter] = JSON.parse(v).to_yaml + "---\n"
76
- end
77
- opts.on("--pr-label [LABEL]", "Setup custom label for pull requests section. Default is \"**Merged pull requests:**\"") do |v|
78
- options[:merge_prefix] = v
79
- end
80
- opts.on("--[no-]issues", "Include closed issues in changelog. Default is true") do |v|
81
- options[:issues] = v
82
- end
83
- opts.on("--[no-]issues-wo-labels", "Include closed issues without labels in changelog. Default is true") do |v|
84
- options[:add_issues_wo_labels] = v
85
- end
86
- opts.on("--[no-]pr-wo-labels", "Include pull requests without labels in changelog. Default is true") do |v|
87
- options[:add_pr_wo_labels] = v
88
- end
89
- opts.on("--[no-]pull-requests", "Include pull-requests in changelog. Default is true") do |v|
90
- options[:pulls] = v
91
- end
92
- opts.on("--[no-]filter-by-milestone", "Use milestone to detect when issue was resolved. Default is true") do |last|
93
- options[:filter_issues_by_milestone] = last
94
- end
95
- opts.on("--[no-]author", "Add author of pull-request in the end. Default is true") do |author|
96
- options[:author] = author
97
- end
98
- opts.on("--usernames-as-github-logins", "Use GitHub tags instead of Markdown links for the author of an issue or pull-request.") do |v|
99
- options[:usernames_as_github_logins] = v
100
- end
101
- opts.on("--unreleased-only", "Generate log from unreleased closed issues only.") do |v|
102
- options[:unreleased_only] = v
103
- end
104
- opts.on("--[no-]unreleased", "Add to log unreleased closed issues. Default is true") do |v|
105
- options[:unreleased] = v
106
- end
107
- opts.on("--unreleased-label [label]", "Setup custom label for unreleased closed issues section. Default is \"**Unreleased:**\"") do |v|
108
- options[:unreleased_label] = v
109
- end
110
- opts.on("--[no-]compare-link", "Include compare link (Full Changelog) between older version and newer version. Default is true") do |v|
111
- options[:compare_link] = v
112
- end
113
- opts.on("--include-labels x,y,z", Array, "Only issues with the specified labels will be included in the changelog.") do |list|
114
- options[:include_labels] = list
115
- end
116
- opts.on("--exclude-labels x,y,z", Array, "Issues with the specified labels will be always excluded from changelog. Default is 'duplicate,question,invalid,wontfix'") do |list|
117
- options[:exclude_labels] = list
118
- end
119
- opts.on("--bug-labels x,y,z", Array, 'Issues with the specified labels will be always added to "Fixed bugs" section. Default is \'bug,Bug\'') do |list|
120
- options[:bug_labels] = list
121
- end
122
- opts.on("--enhancement-labels x,y,z", Array, 'Issues with the specified labels will be always added to "Implemented enhancements" section. Default is \'enhancement,Enhancement\'') do |list|
123
- options[:enhancement_labels] = list
124
- end
125
- opts.on("--breaking-labels x,y,z", Array, 'Issues with these labels will be added to a new section, called "Breaking Changes". Default is \'backwards-incompatible\'') do |list|
126
- options[:breaking_labels] = list
127
- end
128
- opts.on("--issue-line-labels x,y,z", Array, 'The specified labels will be shown in brackets next to each matching issue. Use "ALL" to show all labels. Default is [].') do |list|
129
- options[:issue_line_labels] = list
130
- end
131
- opts.on("--exclude-tags x,y,z", Array, "Change log will exclude specified tags") do |list|
132
- options[:exclude_tags] = list
133
- end
134
- opts.on("--exclude-tags-regex [REGEX]", "Apply a regular expression on tag names so that they can be excluded, for example: --exclude-tags-regex \".*\+\d{1,}\" ") do |last|
135
- options[:exclude_tags_regex] = last
136
- end
137
- opts.on("--since-tag x", "Change log will start after specified tag") do |v|
138
- options[:since_tag] = v
139
- end
140
- opts.on("--due-tag x", "Change log will end before specified tag") do |v|
141
- options[:due_tag] = v
142
- end
143
- opts.on("--max-issues [NUMBER]", Integer, "Max number of issues to fetch from GitHub. Default is unlimited") do |max|
144
- options[:max_issues] = max
145
- end
146
- opts.on("--release-url [URL]", "The URL to point to for release links, in printf format (with the tag as variable).") do |url|
147
- options[:release_url] = url
148
- end
149
- opts.on("--github-site [URL]", "The Enterprise Github site on which your project is hosted.") do |last|
150
- options[:github_site] = last
151
- end
152
- opts.on("--github-api [URL]", "The enterprise endpoint to use for your Github API.") do |last|
153
- options[:github_endpoint] = last
154
- end
155
- opts.on("--simple-list", "Create simple list from issues and pull requests. Default is false.") do |v|
156
- options[:simple_list] = v
157
- end
158
- opts.on("--future-release [RELEASE-VERSION]", "Put the unreleased changes in the specified release number.") do |future_release|
159
- options[:future_release] = future_release
160
- end
161
- opts.on("--release-branch [RELEASE-BRANCH]", "Limit pull requests to the release branch, such as master or release") do |release_branch|
162
- options[:release_branch] = release_branch
163
- end
164
- opts.on("--[no-]http-cache", "Use HTTP Cache to cache Github API requests (useful for large repos) Default is true.") do |http_cache|
165
- options[:http_cache] = http_cache
166
- end
167
- opts.on("--cache-file [CACHE-FILE]", "Filename to use for cache. Default is github-changelog-http-cache in a temporary directory.") do |cache_file|
168
- options[:cache_file] = cache_file
169
- end
170
- opts.on("--cache-log [CACHE-LOG]", "Filename to use for cache log. Default is github-changelog-logger.log in a temporary directory.") do |cache_log|
171
- options[:cache_log] = cache_log
172
- end
173
- opts.on("--ssl-ca-file [PATH]", "Path to cacert.pem file. Default is a bundled lib/github_changelog_generator/ssl_certs/cacert.pem. Respects SSL_CA_PATH.") do |ssl_ca_file|
174
- options[:ssl_ca_file] = ssl_ca_file
175
- end
176
- opts.on("--require x,y,z", Array, "Path to Ruby file(s) to require.") do |paths|
177
- options[:require] = paths
178
- end
179
- opts.on("--[no-]verbose", "Run verbosely. Default is true") do |v|
180
- options[:verbose] = v
181
- end
182
- opts.on("-v", "--version", "Print version number") do |_v|
183
- puts "Version: #{GitHubChangelogGenerator::VERSION}"
184
- exit
185
- end
186
- opts.on("-h", "--help", "Displays Help") do
187
- puts opts
188
- exit
189
- end
38
+ Kernel.abort
190
39
  end
191
- end
192
40
 
193
- # @return [Options] Default options
194
- def self.default_options
195
- Options.new(
196
- date_format: "%Y-%m-%d",
197
- output: "CHANGELOG.md",
198
- base: "HISTORY.md",
199
- issues: true,
200
- add_issues_wo_labels: true,
201
- add_pr_wo_labels: true,
202
- pulls: true,
203
- filter_issues_by_milestone: true,
204
- author: true,
205
- unreleased: true,
206
- unreleased_label: "Unreleased",
207
- compare_link: true,
208
- enhancement_labels: ["enhancement", "Enhancement", "Type: Enhancement"],
209
- bug_labels: ["bug", "Bug", "Type: Bug"],
210
- exclude_labels: ["duplicate", "question", "invalid", "wontfix", "Duplicate", "Question", "Invalid", "Wontfix", "Meta: Exclude From Changelog"],
211
- breaking_labels: %w[backwards-incompatible breaking],
212
- issue_line_labels: [],
213
- max_issues: nil,
214
- simple_list: false,
215
- ssl_ca_file: nil,
216
- verbose: true,
217
- header: "# Change Log",
218
- merge_prefix: "**Merged pull requests:**",
219
- issue_prefix: "**Closed issues:**",
220
- bug_prefix: "**Fixed bugs:**",
221
- enhancement_prefix: "**Implemented enhancements:**",
222
- breaking_prefix: "**Breaking changes:**",
223
- http_cache: true,
224
- require: []
225
- )
41
+ # @return [Options] Default options
42
+ def default_options
43
+ Options.new(
44
+ date_format: "%Y-%m-%d",
45
+ output: "CHANGELOG.md",
46
+ base: "HISTORY.md",
47
+ issues: true,
48
+ add_issues_wo_labels: true,
49
+ add_pr_wo_labels: true,
50
+ pulls: true,
51
+ filter_issues_by_milestone: true,
52
+ issues_of_open_milestones: true,
53
+ author: true,
54
+ unreleased: true,
55
+ unreleased_label: "Unreleased",
56
+ compare_link: true,
57
+ exclude_labels: ["duplicate", "question", "invalid", "wontfix", "Duplicate", "Question", "Invalid", "Wontfix", "Meta: Exclude From Changelog"],
58
+ summary_labels: ["Release summary", "release-summary", "Summary", "summary"],
59
+ breaking_labels: ["backwards-incompatible", "Backwards incompatible", "breaking"],
60
+ enhancement_labels: ["enhancement", "Enhancement", "Type: Enhancement"],
61
+ bug_labels: ["bug", "Bug", "Type: Bug"],
62
+ deprecated_labels: ["deprecated", "Deprecated", "Type: Deprecated"],
63
+ removed_labels: ["removed", "Removed", "Type: Removed"],
64
+ security_labels: ["security", "Security", "Type: Security"],
65
+ configure_sections: {},
66
+ add_sections: {},
67
+ issue_line_labels: [],
68
+ max_issues: nil,
69
+ simple_list: false,
70
+ ssl_ca_file: nil,
71
+ verbose: true,
72
+ header: "# Changelog",
73
+ merge_prefix: "**Merged pull requests:**",
74
+ issue_prefix: "**Closed issues:**",
75
+ summary_prefix: "",
76
+ breaking_prefix: "**Breaking changes:**",
77
+ enhancement_prefix: "**Implemented enhancements:**",
78
+ bug_prefix: "**Fixed bugs:**",
79
+ deprecated_prefix: "**Deprecated:**",
80
+ removed_prefix: "**Removed:**",
81
+ security_prefix: "**Security fixes:**",
82
+ http_cache: true,
83
+ require: [],
84
+ config_file: ".github_changelog_generator"
85
+ )
86
+ end
226
87
  end
227
88
  end
228
89
  end
@@ -5,6 +5,28 @@ require "pathname"
5
5
  module GitHubChangelogGenerator
6
6
  ParserError = Class.new(StandardError)
7
7
 
8
+ class FileParserChooser
9
+ def initialize(options)
10
+ @options = options
11
+ @config_file = Pathname.new(options[:config_file])
12
+ end
13
+
14
+ def parse!(_argv)
15
+ return nil unless (path = resolve_path)
16
+
17
+ ParserFile.new(@options, File.open(path)).parse!
18
+ end
19
+
20
+ def resolve_path
21
+ return @config_file if @config_file.exist?
22
+
23
+ path = @config_file.expand_path
24
+ return path if File.exist?(path)
25
+
26
+ nil
27
+ end
28
+ end
29
+
8
30
  # ParserFile is a configuration file reader which sets options in the
9
31
  # given Hash.
10
32
  #
@@ -22,30 +44,25 @@ module GitHubChangelogGenerator
22
44
  #
23
45
  class ParserFile
24
46
  # @param options [Hash] options to be configured from file contents
25
- # @param file [nil,IO] configuration file handle, defaults to opening `.github_changelog_generator`
26
- def initialize(options, file = open_settings_file)
47
+ # @param io [nil, IO] configuration file handle
48
+ def initialize(options, io = nil)
27
49
  @options = options
28
- @file = file
50
+ @io = io
29
51
  end
30
52
 
31
53
  # Sets options using configuration file content
32
54
  def parse!
33
- return unless @file
34
- @file.each_with_index { |line, i| parse_line!(line, i + 1) }
35
- @file.close
55
+ return unless @io
56
+
57
+ @io.each_with_index { |line, i| parse_line!(line, i + 1) }
58
+ @io.close
36
59
  end
37
60
 
38
61
  private
39
62
 
40
- FILENAME = ".github_changelog_generator"
41
-
42
- def open_settings_file
43
- path = Pathname(File.expand_path(FILENAME))
44
- File.open(path) if path.exist?
45
- end
46
-
47
63
  def parse_line!(line, line_number)
48
64
  return if non_configuration_line?(line)
65
+
49
66
  option_name, value = extract_pair(line)
50
67
  @options[option_key_for(option_name)] = convert_value(value, option_name)
51
68
  rescue StandardError
@@ -54,7 +71,7 @@ module GitHubChangelogGenerator
54
71
 
55
72
  # Returns true if the line starts with a pound sign or a semi-colon.
56
73
  def non_configuration_line?(line)
57
- line =~ /^[\#;]/ || line =~ /^[\s]+$/
74
+ line =~ /^[\#;]/ || line =~ /^\s+$/
58
75
  end
59
76
 
60
77
  # Returns a the option name as a symbol and its string value sans newlines.
@@ -66,8 +83,10 @@ module GitHubChangelogGenerator
66
83
  [key.tr("-", "_").to_sym, value.gsub(/[\n\r]+/, "")]
67
84
  end
68
85
 
69
- KNOWN_ARRAY_KEYS = %i[exclude_labels include_labels bug_labels
70
- enhancement_labels breaking_labels issue_line_labels between_tags exclude_tags]
86
+ KNOWN_ARRAY_KEYS = %i[exclude_labels include_labels
87
+ summary_labels breaking_labels enhancement_labels bug_labels
88
+ deprecated_labels removed_labels security_labels
89
+ issue_line_labels between_tags exclude_tags]
71
90
  KNOWN_INTEGER_KEYS = [:max_issues]
72
91
 
73
92
  def convert_value(value, option_name)