github_changelog_generator 1.15.0.pre.alpha → 1.16.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 (63) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +1 -1
  3. data/README.md +332 -275
  4. data/Rakefile +3 -4
  5. data/bin/git-generate-changelog +1 -1
  6. data/lib/github_changelog_generator.rb +10 -6
  7. data/lib/github_changelog_generator/generator/entry.rb +218 -0
  8. data/lib/github_changelog_generator/generator/generator.rb +126 -104
  9. data/lib/github_changelog_generator/generator/generator_fetcher.rb +139 -23
  10. data/lib/github_changelog_generator/generator/generator_processor.rb +59 -27
  11. data/lib/github_changelog_generator/generator/generator_tags.rb +26 -22
  12. data/lib/github_changelog_generator/generator/section.rb +124 -0
  13. data/lib/github_changelog_generator/helper.rb +1 -1
  14. data/lib/github_changelog_generator/octo_fetcher.rb +261 -130
  15. data/lib/github_changelog_generator/options.rb +74 -1
  16. data/lib/github_changelog_generator/parser.rb +120 -176
  17. data/lib/github_changelog_generator/parser_file.rb +8 -3
  18. data/lib/github_changelog_generator/reader.rb +2 -2
  19. data/lib/github_changelog_generator/task.rb +5 -6
  20. data/lib/github_changelog_generator/version.rb +1 -1
  21. data/man/git-generate-changelog.1 +144 -45
  22. data/man/git-generate-changelog.1.html +157 -84
  23. data/man/git-generate-changelog.html +19 -7
  24. data/man/git-generate-changelog.md +151 -84
  25. data/spec/files/github-changelog-generator.md +114 -114
  26. data/spec/{install-gem-in-bundler.gemfile → install_gem_in_bundler.gemfile} +2 -0
  27. data/spec/spec_helper.rb +2 -6
  28. data/spec/unit/generator/entry_spec.rb +766 -0
  29. data/spec/unit/generator/generator_processor_spec.rb +103 -41
  30. data/spec/unit/generator/generator_spec.rb +47 -0
  31. data/spec/unit/generator/generator_tags_spec.rb +56 -24
  32. data/spec/unit/generator/section_spec.rb +34 -0
  33. data/spec/unit/octo_fetcher_spec.rb +247 -197
  34. data/spec/unit/options_spec.rb +28 -4
  35. data/spec/unit/parse_file_spec.rb +2 -2
  36. data/spec/unit/parser_spec.rb +0 -79
  37. data/spec/unit/reader_spec.rb +4 -4
  38. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits/when_API_is_valid/returns_commits.json +1 -0
  39. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits_before/when_API_is_valid/returns_commits.json +1 -1
  40. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid.json +1 -1
  41. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issue_with_proper_key/values.json +1 -1
  42. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues.json +1 -1
  43. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues_with_labels.json +1 -1
  44. 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
  45. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_requests_with_labels.json +1 -1
  46. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid.json +1 -1
  47. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_correct_pull_request_keys.json +1 -1
  48. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_pull_requests.json +1 -1
  49. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid.json +1 -1
  50. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid/returns_commit.json +1 -1
  51. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid.json +1 -1
  52. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid/returns_date.json +1 -1
  53. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid.json +1 -1
  54. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid/populates_issues.json +1 -1
  55. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid.json +1 -1
  56. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags.json +1 -1
  57. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags_count.json +1 -1
  58. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided.json +1 -1
  59. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided/should_raise_Unauthorized_error.json +1 -1
  60. metadata +71 -38
  61. data/bin/ghclgen +0 -5
  62. data/lib/github_changelog_generator/generator/generator_generation.rb +0 -180
  63. data/spec/unit/generator/generator_generation_spec.rb +0 -17
@@ -1,22 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "delegate"
4
+ require "github_changelog_generator/helper"
5
+
4
6
  module GitHubChangelogGenerator
7
+ # This class wraps Options, and knows a list of known options. Others options
8
+ # will raise exceptions.
5
9
  class Options < SimpleDelegator
10
+ # Raised on initializing with unknown keys in the values hash,
11
+ # and when trying to store a value on an unknown key.
6
12
  UnsupportedOptionError = Class.new(ArgumentError)
7
13
 
14
+ # List of valid option names
8
15
  KNOWN_OPTIONS = %i[
9
16
  add_issues_wo_labels
10
17
  add_pr_wo_labels
18
+ add_sections
11
19
  author
12
20
  base
13
21
  between_tags
22
+ breaking_labels
23
+ breaking_prefix
14
24
  bug_labels
15
25
  bug_prefix
16
26
  cache_file
17
27
  cache_log
18
28
  compare_link
29
+ configure_sections
19
30
  date_format
31
+ deprecated_labels
32
+ deprecated_prefix
20
33
  due_tag
21
34
  enhancement_labels
22
35
  enhancement_prefix
@@ -24,16 +37,18 @@ module GitHubChangelogGenerator
24
37
  exclude_tags
25
38
  exclude_tags_regex
26
39
  filter_issues_by_milestone
40
+ issues_of_open_milestones
27
41
  frontmatter
28
42
  future_release
29
- git_remote
30
43
  github_endpoint
31
44
  github_site
32
45
  header
33
46
  http_cache
34
47
  include_labels
48
+ include_tags_regex
35
49
  issue_prefix
36
50
  issue_line_labels
51
+ issue_line_body
37
52
  issues
38
53
  max_issues
39
54
  merge_prefix
@@ -42,9 +57,17 @@ module GitHubChangelogGenerator
42
57
  pulls
43
58
  release_branch
44
59
  release_url
60
+ removed_labels
61
+ removed_prefix
62
+ require
63
+ security_labels
64
+ security_prefix
45
65
  simple_list
46
66
  since_tag
67
+ since_commit
47
68
  ssl_ca_file
69
+ summary_labels
70
+ summary_prefix
48
71
  token
49
72
  unreleased
50
73
  unreleased_label
@@ -54,26 +77,76 @@ module GitHubChangelogGenerator
54
77
  verbose
55
78
  ]
56
79
 
80
+ # @param values [Hash]
81
+ #
82
+ # @raise [UnsupportedOptionError] if given values contain unknown options
57
83
  def initialize(values)
58
84
  super(values)
59
85
  unsupported_options.any? && raise(UnsupportedOptionError, unsupported_options.inspect)
60
86
  end
61
87
 
88
+ # Set option key to val.
89
+ #
90
+ # @param key [Symbol]
91
+ # @param val [Object]
92
+ #
93
+ # @raise [UnsupportedOptionError] when trying to set an unknown option
62
94
  def []=(key, val)
63
95
  supported_option?(key) || raise(UnsupportedOptionError, key.inspect)
64
96
  values[key] = val
65
97
  end
66
98
 
99
+ # @return [Hash]
67
100
  def to_hash
68
101
  values
69
102
  end
70
103
 
104
+ # Loads the configured Ruby files from the --require option.
105
+ def load_custom_ruby_files
106
+ self[:require].each { |f| require f }
107
+ end
108
+
109
+ # Pretty-prints a censored options hash, if :verbose.
110
+ def print_options
111
+ return unless self[:verbose]
112
+
113
+ Helper.log.info "Using these options:"
114
+ # For ruby 2.5.0+
115
+ censored_values.each do |key, value|
116
+ print(key.inspect, "=>", value.inspect)
117
+ puts ""
118
+ end
119
+ puts ""
120
+ end
121
+
122
+ # Boolean method for whether the user is using configure_sections
123
+ def configure_sections?
124
+ !self[:configure_sections].nil? && !self[:configure_sections].empty?
125
+ end
126
+
127
+ # Boolean method for whether the user is using add_sections
128
+ def add_sections?
129
+ !self[:add_sections].nil? && !self[:add_sections].empty?
130
+ end
131
+
132
+ # @return [Boolean] whether write to `:output`
133
+ def write_to_file?
134
+ self[:output].present?
135
+ end
136
+
71
137
  private
72
138
 
73
139
  def values
74
140
  __getobj__
75
141
  end
76
142
 
143
+ # Returns a censored options hash.
144
+ #
145
+ # @return [Hash] The GitHub `:token` key is censored in the output.
146
+ def censored_values
147
+ values.clone.tap { |opts| opts[:token] = opts[:token].nil? ? "No token used" : "hidden value" }
148
+ end
149
+
77
150
  def unsupported_options
78
151
  values.keys - KNOWN_OPTIONS
79
152
  end
@@ -2,9 +2,9 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "optparse"
5
- require "pp"
6
- require_relative "version"
7
- require_relative "helper"
5
+ require "github_changelog_generator/version"
6
+ require "github_changelog_generator/helper"
7
+
8
8
  module GitHubChangelogGenerator
9
9
  class Parser
10
10
  # parse options with optparse
@@ -19,87 +19,100 @@ module GitHubChangelogGenerator
19
19
  abort [e, parser].join("\n")
20
20
  end
21
21
 
22
- fetch_user_and_project(options)
23
-
24
- abort(parser.banner) unless options[:user] && options[:project]
22
+ unless options[:user] && options[:project]
23
+ warn "Configure which user and project to work on."
24
+ warn "Options --user and --project, or settings to that effect. See --help for more."
25
+ abort(parser.banner)
26
+ end
25
27
 
26
- print_options(options)
28
+ options.print_options
27
29
 
28
30
  options
29
31
  end
30
32
 
31
- # If options set to verbose, print the parsed options.
32
- #
33
- # The GitHub `:token` key is censored in the output.
33
+ # Setup parsing options
34
34
  #
35
- # @param options [Hash] The options to display
36
- # @option options [Boolean] :verbose If false this method does nothing
37
- def self.print_options(options)
38
- if options[:verbose]
39
- Helper.log.info "Performing task with options:"
40
- options_to_display = options.clone
41
- options_to_display[:token] = options_to_display[:token].nil? ? nil : "hidden value"
42
- pp options_to_display
43
- puts ""
44
- end
45
- end
46
-
47
- # setup parsing options
35
+ # @param options [Options]
36
+ # @return [OptionParser]
48
37
  def self.setup_parser(options)
49
- parser = OptionParser.new do |opts| # rubocop:disable Metrics/BlockLength
50
- opts.banner = "Usage: github_changelog_generator [options]"
51
- opts.on("-u", "--user [USER]", "Username of the owner of target GitHub repo") do |last|
38
+ OptionParser.new do |opts| # rubocop:disable Metrics/BlockLength
39
+ opts.banner = "Usage: github_changelog_generator --user USER --project PROJECT [options]"
40
+ 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|
52
41
  options[:user] = last
53
42
  end
54
- opts.on("-p", "--project [PROJECT]", "Name of project on GitHub") do |last|
43
+ opts.on("-p", "--project PROJECT", "Name of project on GitHub.") do |last|
55
44
  options[:project] = last
56
45
  end
57
46
  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|
58
47
  options[:token] = last
59
48
  end
60
- opts.on("-f", "--date-format [FORMAT]", "Date format. Default is %Y-%m-%d") do |last|
49
+ opts.on("-f", "--date-format FORMAT", "Date format. Default is %Y-%m-%d.") do |last|
61
50
  options[:date_format] = last
62
51
  end
63
- opts.on("-o", "--output [NAME]", "Output file. Default is CHANGELOG.md") do |last|
52
+ opts.on("-o", "--output [NAME]", "Output file. To print to STDOUT instead, use blank as path. Default is CHANGELOG.md") do |last|
64
53
  options[:output] = last
65
54
  end
66
55
  opts.on("-b", "--base [NAME]", "Optional base file to append generated changes to.") do |last|
67
56
  options[:base] = last
68
57
  end
69
- opts.on("--bugs-label [LABEL]", "Setup custom label for bug-fixes section. Default is \"**Fixed bugs:**\"") do |v|
70
- options[:bug_prefix] = v
58
+ opts.on("--summary-label [LABEL]", "Set up custom label for the release summary section. Default is \"\".") do |v|
59
+ options[:summary_prefix] = v
71
60
  end
72
- opts.on("--enhancement-label [LABEL]", "Setup custom label for enhancements section. Default is \"**Implemented enhancements:**\"") do |v|
61
+ opts.on("--breaking-label [LABEL]", "Set up custom label for the breaking changes section. Default is \"**Breaking changes:**\".") do |v|
62
+ options[:breaking_prefix] = v
63
+ end
64
+ opts.on("--enhancement-label [LABEL]", "Set up custom label for enhancements section. Default is \"**Implemented enhancements:**\".") do |v|
73
65
  options[:enhancement_prefix] = v
74
66
  end
75
- opts.on("--issues-label [LABEL]", "Setup custom label for closed-issues section. Default is \"**Closed issues:**\"") do |v|
67
+ opts.on("--bugs-label [LABEL]", "Set up custom label for bug-fixes section. Default is \"**Fixed bugs:**\".") do |v|
68
+ options[:bug_prefix] = v
69
+ end
70
+ opts.on("--deprecated-label [LABEL]", "Set up custom label for the deprecated changes section. Default is \"**Deprecated:**\".") do |v|
71
+ options[:deprecated_prefix] = v
72
+ end
73
+ opts.on("--removed-label [LABEL]", "Set up custom label for the removed changes section. Default is \"**Removed:**\".") do |v|
74
+ options[:removed_prefix] = v
75
+ end
76
+ opts.on("--security-label [LABEL]", "Set up custom label for the security changes section. Default is \"**Security fixes:**\".") do |v|
77
+ options[:security_prefix] = v
78
+ end
79
+ opts.on("--issues-label [LABEL]", "Set up custom label for closed-issues section. Default is \"**Closed issues:**\".") do |v|
76
80
  options[:issue_prefix] = v
77
81
  end
78
- opts.on("--header-label [LABEL]", "Setup custom header label. Default is \"# Change Log\"") do |v|
82
+ opts.on("--header-label [LABEL]", "Set up custom header label. Default is \"# Changelog\".") do |v|
79
83
  options[:header] = v
80
84
  end
81
- opts.on("--front-matter [JSON]", "Add YAML front matter. Formatted as JSON because it's easier to add on the command line") do |v|
82
- options[:frontmatter] = JSON.parse(v).to_yaml + "---\n"
85
+ opts.on("--configure-sections [Hash, String]", "Define your own set of sections which overrides all default sections.") do |v|
86
+ options[:configure_sections] = v
87
+ end
88
+ opts.on("--add-sections [Hash, String]", "Add new sections but keep the default sections.") do |v|
89
+ options[:add_sections] = v
83
90
  end
84
- opts.on("--pr-label [LABEL]", "Setup custom label for pull requests section. Default is \"**Merged pull requests:**\"") do |v|
91
+ opts.on("--front-matter [JSON]", "Add YAML front matter. Formatted as JSON because it's easier to add on the command line.") do |v|
92
+ options[:frontmatter] = "#{JSON.parse(v).to_yaml}---\n"
93
+ end
94
+ opts.on("--pr-label [LABEL]", "Set up custom label for pull requests section. Default is \"**Merged pull requests:**\".") do |v|
85
95
  options[:merge_prefix] = v
86
96
  end
87
- opts.on("--[no-]issues", "Include closed issues in changelog. Default is true") do |v|
97
+ opts.on("--[no-]issues", "Include closed issues in changelog. Default is true.") do |v|
88
98
  options[:issues] = v
89
99
  end
90
- opts.on("--[no-]issues-wo-labels", "Include closed issues without labels in changelog. Default is true") do |v|
100
+ opts.on("--[no-]issues-wo-labels", "Include closed issues without labels in changelog. Default is true.") do |v|
91
101
  options[:add_issues_wo_labels] = v
92
102
  end
93
- opts.on("--[no-]pr-wo-labels", "Include pull requests without labels in changelog. Default is true") do |v|
103
+ opts.on("--[no-]pr-wo-labels", "Include pull requests without labels in changelog. Default is true.") do |v|
94
104
  options[:add_pr_wo_labels] = v
95
105
  end
96
- opts.on("--[no-]pull-requests", "Include pull-requests in changelog. Default is true") do |v|
106
+ opts.on("--[no-]pull-requests", "Include pull-requests in changelog. Default is true.") do |v|
97
107
  options[:pulls] = v
98
108
  end
99
- opts.on("--[no-]filter-by-milestone", "Use milestone to detect when issue was resolved. Default is true") do |last|
109
+ opts.on("--[no-]filter-by-milestone", "Use milestone to detect when issue was resolved. Default is true.") do |last|
100
110
  options[:filter_issues_by_milestone] = last
101
111
  end
102
- opts.on("--[no-]author", "Add author of pull-request in the end. Default is true") do |author|
112
+ opts.on("--[no-]issues-of-open-milestones", "Include issues of open milestones. Default is true.") do |v|
113
+ options[:issues_of_open_milestones] = v
114
+ end
115
+ opts.on("--[no-]author", "Add author of pull request at the end. Default is true.") do |author|
103
116
  options[:author] = author
104
117
  end
105
118
  opts.on("--usernames-as-github-logins", "Use GitHub tags instead of Markdown links for the author of an issue or pull-request.") do |v|
@@ -108,64 +121,85 @@ module GitHubChangelogGenerator
108
121
  opts.on("--unreleased-only", "Generate log from unreleased closed issues only.") do |v|
109
122
  options[:unreleased_only] = v
110
123
  end
111
- opts.on("--[no-]unreleased", "Add to log unreleased closed issues. Default is true") do |v|
124
+ opts.on("--[no-]unreleased", "Add to log unreleased closed issues. Default is true.") do |v|
112
125
  options[:unreleased] = v
113
126
  end
114
- opts.on("--unreleased-label [label]", "Setup custom label for unreleased closed issues section. Default is \"**Unreleased:**\"") do |v|
127
+ opts.on("--unreleased-label [label]", "Set up custom label for unreleased closed issues section. Default is \"**Unreleased:**\".") do |v|
115
128
  options[:unreleased_label] = v
116
129
  end
117
- opts.on("--[no-]compare-link", "Include compare link (Full Changelog) between older version and newer version. Default is true") do |v|
130
+ opts.on("--[no-]compare-link", "Include compare link (Full Changelog) between older version and newer version. Default is true.") do |v|
118
131
  options[:compare_link] = v
119
132
  end
120
- opts.on("--include-labels x,y,z", Array, "Only issues with the specified labels will be included in the changelog.") do |list|
133
+ opts.on("--include-labels x,y,z", Array, "Of the labeled issues, only include the ones with the specified labels.") do |list|
121
134
  options[:include_labels] = list
122
135
  end
123
- 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|
136
+ opts.on("--exclude-labels x,y,z", Array, "Issues with the specified labels will be excluded from changelog. Default is 'duplicate,question,invalid,wontfix'.") do |list|
124
137
  options[:exclude_labels] = list
125
138
  end
126
- 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|
127
- options[:bug_labels] = list
139
+ opts.on("--summary-labels x,y,z", Array, 'Issues with these labels will be added to a new section, called "Release Summary". The section display only body of issues. Default is \'release-summary,summary\'.') do |list|
140
+ options[:summary_labels] = list
141
+ end
142
+ 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,breaking\'.') do |list|
143
+ options[:breaking_labels] = list
128
144
  end
129
- 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|
145
+ opts.on("--enhancement-labels x,y,z", Array, 'Issues with the specified labels will be added to "Implemented enhancements" section. Default is \'enhancement,Enhancement\'.') do |list|
130
146
  options[:enhancement_labels] = list
131
147
  end
148
+ opts.on("--bug-labels x,y,z", Array, 'Issues with the specified labels will be added to "Fixed bugs" section. Default is \'bug,Bug\'.') do |list|
149
+ options[:bug_labels] = list
150
+ end
151
+ opts.on("--deprecated-labels x,y,z", Array, 'Issues with the specified labels will be added to a section called "Deprecated". Default is \'deprecated,Deprecated\'.') do |list|
152
+ options[:deprecated_labels] = list
153
+ end
154
+ opts.on("--removed-labels x,y,z", Array, 'Issues with the specified labels will be added to a section called "Removed". Default is \'removed,Removed\'.') do |list|
155
+ options[:removed_labels] = list
156
+ end
157
+ opts.on("--security-labels x,y,z", Array, 'Issues with the specified labels will be added to a section called "Security fixes". Default is \'security,Security\'.') do |list|
158
+ options[:security_labels] = list
159
+ end
132
160
  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|
133
161
  options[:issue_line_labels] = list
134
162
  end
135
- opts.on("--exclude-tags x,y,z", Array, "Change log will exclude specified tags") do |list|
163
+ opts.on("--include-tags-regex [REGEX]", "Apply a regular expression on tag names so that they can be included, for example: --include-tags-regex \".*\+\d{1,}\".") do |last|
164
+ options[:include_tags_regex] = last
165
+ end
166
+ opts.on("--exclude-tags x,y,z", Array, "Changelog will exclude specified tags") do |list|
136
167
  options[:exclude_tags] = list
137
168
  end
138
- 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|
169
+ 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|
139
170
  options[:exclude_tags_regex] = last
140
171
  end
141
- opts.on("--since-tag x", "Change log will start after specified tag") do |v|
172
+ opts.on("--since-tag x", "Changelog will start after specified tag.") do |v|
142
173
  options[:since_tag] = v
143
174
  end
144
- opts.on("--due-tag x", "Change log will end before specified tag") do |v|
175
+ opts.on("--due-tag x", "Changelog will end before specified tag.") do |v|
145
176
  options[:due_tag] = v
146
177
  end
147
- opts.on("--max-issues [NUMBER]", Integer, "Max number of issues to fetch from GitHub. Default is unlimited") do |max|
178
+ opts.on("--since-commit x", "Fetch only commits after this time. eg. \"2017-01-01 10:00:00\"") do |v|
179
+ options[:since_commit] = v
180
+ end
181
+ opts.on("--max-issues [NUMBER]", Integer, "Maximum number of issues to fetch from GitHub. Default is unlimited.") do |max|
148
182
  options[:max_issues] = max
149
183
  end
150
184
  opts.on("--release-url [URL]", "The URL to point to for release links, in printf format (with the tag as variable).") do |url|
151
185
  options[:release_url] = url
152
186
  end
153
- opts.on("--github-site [URL]", "The Enterprise Github site on which your project is hosted.") do |last|
187
+ opts.on("--github-site [URL]", "The Enterprise GitHub site where your project is hosted.") do |last|
154
188
  options[:github_site] = last
155
189
  end
156
- opts.on("--github-api [URL]", "The enterprise endpoint to use for your Github API.") do |last|
190
+ opts.on("--github-api [URL]", "The enterprise endpoint to use for your GitHub API.") do |last|
157
191
  options[:github_endpoint] = last
158
192
  end
159
- opts.on("--simple-list", "Create simple list from issues and pull requests. Default is false.") do |v|
193
+ opts.on("--simple-list", "Create a simple list from issues and pull requests. Default is false.") do |v|
160
194
  options[:simple_list] = v
161
195
  end
162
196
  opts.on("--future-release [RELEASE-VERSION]", "Put the unreleased changes in the specified release number.") do |future_release|
163
197
  options[:future_release] = future_release
164
198
  end
165
- opts.on("--release-branch [RELEASE-BRANCH]", "Limit pull requests to the release branch, such as master or release") do |release_branch|
199
+ opts.on("--release-branch [RELEASE-BRANCH]", "Limit pull requests to the release branch, such as master or release.") do |release_branch|
166
200
  options[:release_branch] = release_branch
167
201
  end
168
- opts.on("--[no-]http-cache", "Use HTTP Cache to cache Github API requests (useful for large repos) Default is true.") do |http_cache|
202
+ opts.on("--[no-]http-cache", "Use HTTP Cache to cache GitHub API requests (useful for large repos). Default is true.") do |http_cache|
169
203
  options[:http_cache] = http_cache
170
204
  end
171
205
  opts.on("--cache-file [CACHE-FILE]", "Filename to use for cache. Default is github-changelog-http-cache in a temporary directory.") do |cache_file|
@@ -177,22 +211,24 @@ module GitHubChangelogGenerator
177
211
  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|
178
212
  options[:ssl_ca_file] = ssl_ca_file
179
213
  end
180
- opts.on("--[no-]verbose", "Run verbosely. Default is true") do |v|
214
+ opts.on("--require x,y,z", Array, "Path to Ruby file(s) to require before generating changelog.") do |paths|
215
+ options[:require] = paths
216
+ end
217
+ opts.on("--[no-]verbose", "Run verbosely. Default is true.") do |v|
181
218
  options[:verbose] = v
182
219
  end
183
- opts.on("-v", "--version", "Print version number") do |_v|
220
+ opts.on("-v", "--version", "Print version number.") do |_v|
184
221
  puts "Version: #{GitHubChangelogGenerator::VERSION}"
185
222
  exit
186
223
  end
187
- opts.on("-h", "--help", "Displays Help") do
224
+ opts.on("-h", "--help", "Displays Help.") do
188
225
  puts opts
189
226
  exit
190
227
  end
191
228
  end
192
- parser
193
229
  end
194
230
 
195
- # @return [Hash] Default options
231
+ # @return [Options] Default options
196
232
  def self.default_options
197
233
  Options.new(
198
234
  date_format: "%Y-%m-%d",
@@ -203,131 +239,39 @@ module GitHubChangelogGenerator
203
239
  add_pr_wo_labels: true,
204
240
  pulls: true,
205
241
  filter_issues_by_milestone: true,
242
+ issues_of_open_milestones: true,
206
243
  author: true,
207
244
  unreleased: true,
208
245
  unreleased_label: "Unreleased",
209
246
  compare_link: true,
247
+ exclude_labels: ["duplicate", "question", "invalid", "wontfix", "Duplicate", "Question", "Invalid", "Wontfix", "Meta: Exclude From Changelog"],
248
+ summary_labels: ["Release summary", "release-summary", "Summary", "summary"],
249
+ breaking_labels: ["backwards-incompatible", "Backwards incompatible", "breaking"],
210
250
  enhancement_labels: ["enhancement", "Enhancement", "Type: Enhancement"],
211
251
  bug_labels: ["bug", "Bug", "Type: Bug"],
212
- exclude_labels: ["duplicate", "question", "invalid", "wontfix", "Duplicate", "Question", "Invalid", "Wontfix", "Meta: Exclude From Changelog"],
252
+ deprecated_labels: ["deprecated", "Deprecated", "Type: Deprecated"],
253
+ removed_labels: ["removed", "Removed", "Type: Removed"],
254
+ security_labels: ["security", "Security", "Type: Security"],
255
+ configure_sections: {},
256
+ add_sections: {},
213
257
  issue_line_labels: [],
214
258
  max_issues: nil,
215
259
  simple_list: false,
216
260
  ssl_ca_file: nil,
217
261
  verbose: true,
218
- header: "# Change Log",
262
+ header: "# Changelog",
219
263
  merge_prefix: "**Merged pull requests:**",
220
264
  issue_prefix: "**Closed issues:**",
221
- bug_prefix: "**Fixed bugs:**",
265
+ summary_prefix: "",
266
+ breaking_prefix: "**Breaking changes:**",
222
267
  enhancement_prefix: "**Implemented enhancements:**",
223
- git_remote: "origin",
224
- http_cache: true
268
+ bug_prefix: "**Fixed bugs:**",
269
+ deprecated_prefix: "**Deprecated:**",
270
+ removed_prefix: "**Removed:**",
271
+ security_prefix: "**Security fixes:**",
272
+ http_cache: true,
273
+ require: []
225
274
  )
226
275
  end
227
-
228
- # If `:user` or `:project` not set in options, try setting them
229
- # Valid unnamed parameters:
230
- # 1) in 1 param: repo_name/project
231
- # 2) in 2 params: repo name project
232
- def self.fetch_user_and_project(options)
233
- if options[:user].nil? || options[:project].nil?
234
- user, project = user_and_project_from_git(options, ARGV[0], ARGV[1])
235
- options[:user] ||= user
236
- options[:project] ||= project
237
- end
238
- end
239
-
240
- # Sets `:user` and `:project` in `options` from CLI arguments or `git remote`
241
- # @param [String] arg0 first argument in cli
242
- # @param [String] arg1 second argument in cli
243
- # @return [Array<String>] user and project, or nil if unsuccessful
244
- def self.user_and_project_from_git(options, arg0 = nil, arg1 = nil)
245
- user, project = user_project_from_option(arg0, arg1, options[:github_site])
246
- unless user && project
247
- if ENV["RUBYLIB"] =~ /ruby-debug-ide/
248
- user = "skywinder"
249
- project = "changelog_test"
250
- else
251
- remote = `git config --get remote.#{options[:git_remote]}.url`
252
- user, project = user_project_from_remote(remote)
253
- end
254
- end
255
-
256
- [user, project]
257
- end
258
-
259
- # Returns GitHub username and project from CLI arguments
260
- #
261
- # @param arg0 [String] This parameter takes two forms: Either a full
262
- # GitHub URL, or a 'username/projectname', or
263
- # simply a GitHub username
264
- # @param arg1 [String] If arg0 is given as a username,
265
- # then arg1 can given as a projectname
266
- # @param github_site [String] Domain name of GitHub site
267
- #
268
- # @return [Array, nil] user and project, or nil if unsuccessful
269
- def self.user_project_from_option(arg0, arg1, github_site)
270
- user = nil
271
- project = nil
272
- github_site ||= "github.com"
273
- if arg0 && !arg1
274
- # this match should parse strings such "https://github.com/skywinder/Github-Changelog-Generator" or
275
- # "skywinder/Github-Changelog-Generator" to user and name
276
- match = /(?:.+#{Regexp.escape(github_site)}\/)?(.+)\/(.+)/.match(arg0)
277
-
278
- begin
279
- param = match[2].nil?
280
- rescue StandardError
281
- puts "Can't detect user and name from first parameter: '#{arg0}' -> exit'"
282
- return
283
- end
284
- if param
285
- return
286
- else
287
- user = match[1]
288
- project = match[2]
289
- end
290
- end
291
- [user, project]
292
- end
293
-
294
- # These patterns match these formats:
295
- #
296
- # ```
297
- # origin git@github.com:skywinder/Github-Changelog-Generator.git (fetch)
298
- # git@github.com:skywinder/Github-Changelog-Generator.git
299
- # ```
300
- #
301
- # and
302
- #
303
- # ```
304
- # origin https://github.com/skywinder/ChangelogMerger (fetch)
305
- # https://github.com/skywinder/ChangelogMerger
306
- # ```
307
- GIT_REMOTE_PATTERNS = [
308
- /.*(?:[:\/])(?<user>(?:-|\w|\.)*)\/(?<project>(?:-|\w|\.)*)(?:\.git).*/,
309
- /.*\/(?<user>(?:-|\w|\.)*)\/(?<project>(?:-|\w|\.)*).*/
310
- ]
311
-
312
- # Returns GitHub username and project from git remote output
313
- #
314
- # @param git_remote_output [String] Output of git remote command
315
- #
316
- # @return [Array] user and project
317
- def self.user_project_from_remote(git_remote_output)
318
- user = nil
319
- project = nil
320
- GIT_REMOTE_PATTERNS.each do |git_remote_pattern|
321
- git_remote_pattern =~ git_remote_output
322
-
323
- if Regexp.last_match
324
- user = Regexp.last_match(:user)
325
- project = Regexp.last_match(:project)
326
- break
327
- end
328
- end
329
-
330
- [user, project]
331
- end
332
276
  end
333
277
  end