github_changelog_generator 1.13.2 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/github_changelog_generator.rb +6 -1
  4. data/lib/github_changelog_generator/generator/generator.rb +28 -28
  5. data/lib/github_changelog_generator/generator/generator_fetcher.rb +23 -20
  6. data/lib/github_changelog_generator/generator/generator_generation.rb +40 -53
  7. data/lib/github_changelog_generator/generator/generator_processor.rb +32 -22
  8. data/lib/github_changelog_generator/generator/generator_tags.rb +77 -46
  9. data/lib/github_changelog_generator/octo_fetcher.rb +363 -0
  10. data/lib/github_changelog_generator/options.rb +92 -0
  11. data/lib/github_changelog_generator/parser.rb +21 -5
  12. data/lib/github_changelog_generator/parser_file.rb +2 -2
  13. data/lib/github_changelog_generator/version.rb +1 -1
  14. data/man/git-generate-changelog.1 +44 -2
  15. data/man/git-generate-changelog.1.html +290 -0
  16. data/man/git-generate-changelog.md +29 -1
  17. data/spec/spec_helper.rb +21 -0
  18. data/spec/unit/generator/generator_processor_spec.rb +4 -4
  19. data/spec/unit/generator/generator_tags_spec.rb +43 -40
  20. data/spec/unit/octo_fetcher_spec.rb +528 -0
  21. data/spec/unit/options_spec.rb +42 -0
  22. data/spec/unit/reader_spec.rb +0 -4
  23. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid.json +1 -0
  24. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issue_with_proper_key/values.json +1 -0
  25. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues.json +1 -0
  26. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues_with_labels.json +1 -0
  27. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_request_with_proper_key/values.json +1 -0
  28. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_requests_with_labels.json +1 -0
  29. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid.json +1 -0
  30. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_correct_pull_request_keys.json +1 -0
  31. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_pull_requests.json +1 -0
  32. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid.json +1 -0
  33. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid/returns_commit.json +1 -0
  34. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid.json +1 -0
  35. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid/returns_date.json +1 -0
  36. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid.json +1 -0
  37. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid/populates_issues.json +1 -0
  38. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid.json +1 -0
  39. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags.json +1 -0
  40. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags_count.json +1 -0
  41. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided.json +1 -0
  42. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided/should_raise_Unauthorized_error.json +1 -0
  43. metadata +97 -12
  44. data/lib/CHANGELOG.md +0 -58
  45. data/lib/github_changelog_generator/fetcher.rb +0 -226
  46. data/spec/unit/fetcher_spec.rb +0 -60
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 336a1ac8b95b7e15cb682b2f073fcad6c3de1eae
4
- data.tar.gz: 2ab6a245bf80a345de5fd1cedeab7aa49779b53b
3
+ metadata.gz: 28ce5bfbf45c423de7b0e00662def73cb31dab48
4
+ data.tar.gz: 0f0ce064c6c069ce90d0186f308be3bdfce966cf
5
5
  SHA512:
6
- metadata.gz: 78bc7037133a625102719ed21ea878e1f065dd92252052142c973be0f7cfa3236e06916a88574c1ae9534cdde100b8b202dc7aa40445a891c14a980de9608953
7
- data.tar.gz: 887ee7d59c311859c8bfe55488f6a3985551fd28e16f981b8de43244239e7660af5f54ab30b8fb1759d2d19eca72968ab3b04d7d31383953bea46cff0c593349
6
+ metadata.gz: a855f3b32548927042e54979e40e296999636c0a2e7fbfb6c3bb5ab228ae013803a15219361b540eb7aa1bac677e0c85ac340de57a8168e8311e29d054aa5947
7
+ data.tar.gz: 4c8412f7522e7941ce4255a2b246c975013cf2fe99534fe716d275e28ce5fe668f00586e42a3605806b900673e71c112a0ae756888131d82b0dd5c113daf4b33
data/README.md CHANGED
@@ -228,7 +228,7 @@ If you're seeing this warning, please do the following:
228
228
 
229
229
  - ***My Ruby version is very old, can I use this?***
230
230
 
231
- When your Ruby is old, and you don't want to upgrade, and your want to
231
+ When your Ruby is old, and you don't want to upgrade, and you want to
232
232
  control which libraries you use, you can use Bundler.
233
233
 
234
234
  In a Gemfile, perhaps in a non-deployed `:development` group, add this
@@ -1,11 +1,16 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require "github_api"
4
+ require "octokit"
5
+ require "faraday-http-cache"
6
+ require "logger"
7
+ require "active_support"
5
8
  require "json"
9
+ require "multi_json"
6
10
  require "benchmark"
7
11
 
8
12
  require_relative "github_changelog_generator/helper"
13
+ require_relative "github_changelog_generator/options"
9
14
  require_relative "github_changelog_generator/parser"
10
15
  require_relative "github_changelog_generator/parser_file"
11
16
  require_relative "github_changelog_generator/generator/generator"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- require_relative "../fetcher"
2
+ require_relative "../octo_fetcher"
3
3
  require_relative "generator_generation"
4
4
  require_relative "generator_fetcher"
5
5
  require_relative "generator_processor"
@@ -11,25 +11,25 @@ module GitHubChangelogGenerator
11
11
  end
12
12
 
13
13
  class Generator
14
- attr_accessor :options, :filtered_tags, :github
14
+ attr_accessor :options, :filtered_tags, :github, :tag_section_mapping, :sorted_tags
15
15
 
16
16
  # A Generator responsible for all logic, related with change log generation from ready-to-parse issues
17
17
  #
18
18
  # Example:
19
19
  # generator = GitHubChangelogGenerator::Generator.new
20
20
  # content = generator.compound_changelog
21
- def initialize(options = nil)
22
- @options = options || {}
21
+ def initialize(options = {})
22
+ @options = options
23
23
  @tag_times_hash = {}
24
- @fetcher = GitHubChangelogGenerator::Fetcher.new @options
24
+ @fetcher = GitHubChangelogGenerator::OctoFetcher.new(options)
25
25
  end
26
26
 
27
27
  def fetch_issues_and_pr
28
28
  issues, pull_requests = @fetcher.fetch_closed_issues_and_pr
29
29
 
30
- @pull_requests = @options[:pulls] ? get_filtered_pull_requests(pull_requests) : []
30
+ @pull_requests = options[:pulls] ? get_filtered_pull_requests(pull_requests) : []
31
31
 
32
- @issues = @options[:issues] ? get_filtered_issues(issues) : []
32
+ @issues = options[:issues] ? get_filtered_issues(issues) : []
33
33
 
34
34
  fetch_events_for_issues_and_pr
35
35
  detect_actual_closed_dates(@issues + @pull_requests)
@@ -61,18 +61,18 @@ module GitHubChangelogGenerator
61
61
  newer_tag_link, newer_tag_name, newer_tag_time = detect_link_tag_time(newer_tag)
62
62
 
63
63
  github_site = options[:github_site] || "https://github.com"
64
- project_url = "#{github_site}/#{@options[:user]}/#{@options[:project]}"
64
+ project_url = "#{github_site}/#{options[:user]}/#{options[:project]}"
65
65
 
66
66
  log = generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_name, project_url)
67
67
 
68
- if @options[:issues]
68
+ if options[:issues]
69
69
  # Generate issues:
70
70
  log += issues_to_log(issues, pull_requests)
71
71
  end
72
72
 
73
- if @options[:pulls]
73
+ if options[:pulls]
74
74
  # Generate pull requests:
75
- log += generate_sub_section(pull_requests, @options[:merge_prefix])
75
+ log += generate_sub_section(pull_requests, options[:merge_prefix])
76
76
  end
77
77
 
78
78
  log
@@ -87,9 +87,9 @@ module GitHubChangelogGenerator
87
87
  log = ""
88
88
  bugs_a, enhancement_a, issues_a = parse_by_sections(issues, pull_requests)
89
89
 
90
- log += generate_sub_section(enhancement_a, @options[:enhancement_prefix])
91
- log += generate_sub_section(bugs_a, @options[:bug_prefix])
92
- log += generate_sub_section(issues_a, @options[:issue_prefix])
90
+ log += generate_sub_section(enhancement_a, options[:enhancement_prefix])
91
+ log += generate_sub_section(bugs_a, options[:bug_prefix])
92
+ log += generate_sub_section(issues_a, options[:issue_prefix])
93
93
  log
94
94
  end
95
95
 
@@ -106,32 +106,32 @@ module GitHubChangelogGenerator
106
106
 
107
107
  issues.each do |dict|
108
108
  added = false
109
- dict.labels.each do |label|
110
- if @options[:bug_labels].include? label.name
111
- bugs_a.push dict
109
+ dict["labels"].each do |label|
110
+ if options[:bug_labels].include?(label["name"])
111
+ bugs_a.push(dict)
112
112
  added = true
113
113
  next
114
114
  end
115
- if @options[:enhancement_labels].include? label.name
116
- enhancement_a.push dict
115
+ if options[:enhancement_labels].include?(label["name"])
116
+ enhancement_a.push(dict)
117
117
  added = true
118
118
  next
119
119
  end
120
120
  end
121
- issues_a.push dict unless added
121
+ issues_a.push(dict) unless added
122
122
  end
123
123
 
124
124
  added_pull_requests = []
125
- pull_requests.each do |dict|
126
- dict.labels.each do |label|
127
- if @options[:bug_labels].include? label.name
128
- bugs_a.push dict
129
- added_pull_requests.push dict
125
+ pull_requests.each do |pr|
126
+ pr["labels"].each do |label|
127
+ if options[:bug_labels].include?(label["name"])
128
+ bugs_a.push(pr)
129
+ added_pull_requests.push(pr)
130
130
  next
131
131
  end
132
- if @options[:enhancement_labels].include? label.name
133
- enhancement_a.push dict
134
- added_pull_requests.push dict
132
+ if options[:enhancement_labels].include?(label["name"])
133
+ enhancement_a.push(pr)
134
+ added_pull_requests.push(pr)
135
135
  next
136
136
  end
137
137
  end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
  module GitHubChangelogGenerator
3
3
  class Generator
4
+ MAX_THREAD_NUMBER = 25
5
+
4
6
  # Fetch event for issues and pull requests
5
7
  # @return [Array] array of fetched issues
6
8
  def fetch_events_for_issues_and_pr
7
- if @options[:verbose]
9
+ if options[:verbose]
8
10
  print "Fetching events for issues and PR: 0/#{@issues.count + @pull_requests.count}\r"
9
11
  end
10
12
 
@@ -13,48 +15,47 @@ module GitHubChangelogGenerator
13
15
  end
14
16
 
15
17
  # Async fetching of all tags dates
16
- def fetch_tags_dates
17
- print "Fetching tag dates...\r" if @options[:verbose]
18
+ def fetch_tags_dates(tags)
19
+ print "Fetching tag dates...\r" if options[:verbose]
18
20
  # Async fetching tags:
19
21
  threads = []
20
22
  i = 0
21
- all = @filtered_tags.count
22
- @filtered_tags.each do |tag|
23
+ all = tags.count
24
+ tags.each do |tag|
23
25
  print " \r"
24
26
  threads << Thread.new do
25
27
  get_time_of_tag(tag)
26
- print "Fetching tags dates: #{i + 1}/#{all}\r" if @options[:verbose]
28
+ print "Fetching tags dates: #{i + 1}/#{all}\r" if options[:verbose]
27
29
  i += 1
28
30
  end
29
31
  end
30
32
  threads.each(&:join)
31
- puts "Fetching tags dates: #{i}" if @options[:verbose]
33
+ puts "Fetching tags dates: #{i}" if options[:verbose]
32
34
  end
33
35
 
34
36
  # Find correct closed dates, if issues was closed by commits
35
37
  def detect_actual_closed_dates(issues)
36
- print "Fetching closed dates for issues...\r" if @options[:verbose]
38
+ print "Fetching closed dates for issues...\r" if options[:verbose]
37
39
 
38
- max_thread_number = 50
39
- issues.each_slice(max_thread_number) do |issues_slice|
40
+ issues.each_slice(MAX_THREAD_NUMBER) do |issues_slice|
40
41
  threads = []
41
42
  issues_slice.each do |issue|
42
43
  threads << Thread.new { find_closed_date_by_commit(issue) }
43
44
  end
44
45
  threads.each(&:join)
45
46
  end
46
- puts "Fetching closed dates for issues: Done!" if @options[:verbose]
47
+ puts "Fetching closed dates for issues: Done!" if options[:verbose]
47
48
  end
48
49
 
49
50
  # Fill :actual_date parameter of specified issue by closed date of the commit, if it was closed by commit.
50
51
  # @param [Hash] issue
51
52
  def find_closed_date_by_commit(issue)
52
- unless issue[:events].nil?
53
+ unless issue["events"].nil?
53
54
  # if it's PR -> then find "merged event", in case of usual issue -> fond closed date
54
- compare_string = issue[:merged_at].nil? ? "closed" : "merged"
55
+ compare_string = issue["merged_at"].nil? ? "closed" : "merged"
55
56
  # reverse! - to find latest closed event. (event goes in date order)
56
- issue[:events].reverse!.each do |event|
57
- if event[:event].eql? compare_string
57
+ issue["events"].reverse!.each do |event|
58
+ if event["event"].eql? compare_string
58
59
  set_date_from_event(event, issue)
59
60
  break
60
61
  end
@@ -68,15 +69,17 @@ module GitHubChangelogGenerator
68
69
  # @param [Hash] event
69
70
  # @param [Hash] issue
70
71
  def set_date_from_event(event, issue)
71
- if event[:commit_id].nil?
72
- issue[:actual_date] = issue[:closed_at]
72
+ if event["commit_id"].nil?
73
+ issue["actual_date"] = issue["closed_at"]
73
74
  else
74
75
  begin
75
76
  commit = @fetcher.fetch_commit(event)
76
- issue[:actual_date] = commit[:author][:date]
77
+ issue["actual_date"] = commit["commit"]["author"]["date"]
78
+
79
+ # issue['actual_date'] = commit['author']['date']
77
80
  rescue
78
- puts "Warning: Can't fetch commit #{event[:commit_id]}. It is probably referenced from another repo."
79
- issue[:actual_date] = issue[:closed_at]
81
+ puts "Warning: Can't fetch commit #{event['commit_id']}. It is probably referenced from another repo."
82
+ issue["actual_date"] = issue["closed_at"]
80
83
  end
81
84
  end
82
85
  end
@@ -6,50 +6,26 @@ module GitHubChangelogGenerator
6
6
  # @return [String] Generated change log file
7
7
  def compound_changelog
8
8
  fetch_and_filter_tags
9
- sort_tags_by_date(@filtered_tags)
10
9
  fetch_issues_and_pr
11
10
 
12
11
  log = ""
13
- log += @options[:frontmatter] if @options[:frontmatter]
14
- log += "#{@options[:header]}\n\n"
12
+ log += options[:frontmatter] if options[:frontmatter]
13
+ log += "#{options[:header]}\n\n"
15
14
 
16
- log += if @options[:unreleased_only]
15
+ log += if options[:unreleased_only]
17
16
  generate_log_between_tags(filtered_tags[0], nil)
18
17
  else
19
18
  generate_log_for_all_tags
20
19
  end
21
20
 
22
- log += File.read(@options[:base]) if File.file?(@options[:base])
21
+ log += File.read(options[:base]) if File.file?(options[:base])
23
22
 
24
23
  log += "\n\n\\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*"
25
24
  @log = log
26
25
  end
27
26
 
28
- # @return [String] temp method should be removed soon
29
- def generate_for_2_tags(log)
30
- tag1 = @options[:tag1]
31
- tag2 = @options[:tag2]
32
- tags_strings = []
33
- filtered_tags.each { |x| tags_strings.push(x["name"]) }
34
-
35
- if tags_strings.include?(tag1)
36
- if tags_strings.include?(tag2)
37
- to_a = tags_strings.map.with_index.to_a
38
- hash = Hash[to_a]
39
- index1 = hash[tag1]
40
- index2 = hash[tag2]
41
- log += generate_log_between_tags(all_tags[index1], all_tags[index2])
42
- else
43
- raise ChangelogGeneratorError, "Can't find tag #{tag2} -> exit"
44
- end
45
- else
46
- raise ChangelogGeneratorError, "Can't find tag #{tag1} -> exit"
47
- end
48
- log
49
- end
50
-
51
27
  # @param [Array] issues List of issues on sub-section
52
- # @param [String] prefix Nae of sub-section
28
+ # @param [String] prefix Name of sub-section
53
29
  # @return [String] Generate ready-to-go sub-section
54
30
  def generate_sub_section(issues, prefix)
55
31
  log = ""
@@ -77,21 +53,21 @@ module GitHubChangelogGenerator
77
53
  log = ""
78
54
 
79
55
  # Generate date string:
80
- time_string = newer_tag_time.strftime @options[:date_format]
56
+ time_string = newer_tag_time.strftime(options[:date_format])
81
57
 
82
58
  # Generate tag name and link
83
- release_url = if @options[:release_url]
84
- format(@options[:release_url], newer_tag_link)
59
+ release_url = if options[:release_url]
60
+ format(options[:release_url], newer_tag_link)
85
61
  else
86
62
  "#{project_url}/tree/#{newer_tag_link}"
87
63
  end
88
- log += if newer_tag_name.equal? @options[:unreleased_label]
64
+ log += if newer_tag_name.equal?(options[:unreleased_label])
89
65
  "## [#{newer_tag_name}](#{release_url})\n\n"
90
66
  else
91
67
  "## [#{newer_tag_name}](#{release_url}) (#{time_string})\n"
92
68
  end
93
69
 
94
- if @options[:compare_link] && older_tag_link
70
+ if options[:compare_link] && older_tag_link
95
71
  # Generate compare link
96
72
  log += "[Full Changelog](#{project_url}/compare/#{older_tag_link}...#{newer_tag_link})\n\n"
97
73
  end
@@ -119,12 +95,12 @@ module GitHubChangelogGenerator
119
95
  #
120
96
  # @return [Array] filtered issues and pull requests
121
97
  def filter_issues_for_tags(newer_tag, older_tag)
122
- filtered_pull_requests = delete_by_time(@pull_requests, :actual_date, older_tag, newer_tag)
123
- filtered_issues = delete_by_time(@issues, :actual_date, older_tag, newer_tag)
98
+ filtered_pull_requests = delete_by_time(@pull_requests, "actual_date", older_tag, newer_tag)
99
+ filtered_issues = delete_by_time(@issues, "actual_date", older_tag, newer_tag)
124
100
 
125
101
  newer_tag_name = newer_tag.nil? ? nil : newer_tag["name"]
126
102
 
127
- if @options[:filter_issues_by_milestone]
103
+ if options[:filter_issues_by_milestone]
128
104
  # delete excess irrelevant issues (according milestones). Issue #22.
129
105
  filtered_issues = filter_by_milestone(filtered_issues, newer_tag_name, @issues)
130
106
  filtered_pull_requests = filter_by_milestone(filtered_pull_requests, newer_tag_name, @pull_requests)
@@ -135,15 +111,13 @@ module GitHubChangelogGenerator
135
111
  # The full cycle of generation for whole project
136
112
  # @return [String] The complete change log
137
113
  def generate_log_for_all_tags
138
- puts "Generating log..." if @options[:verbose]
114
+ puts "Generating log..." if options[:verbose]
139
115
 
140
116
  log = generate_unreleased_section
141
117
 
142
- (1...filtered_tags.size).each do |index|
143
- log += generate_log_between_tags(filtered_tags[index], filtered_tags[index - 1])
144
- end
145
- if filtered_tags.any?
146
- log += generate_log_between_tags(nil, filtered_tags.last)
118
+ @tag_section_mapping.each_pair do |_tag_section, left_right_tags|
119
+ older_tag, newer_tag = left_right_tags
120
+ log += generate_log_between_tags(older_tag, newer_tag)
147
121
  end
148
122
 
149
123
  log
@@ -151,9 +125,10 @@ module GitHubChangelogGenerator
151
125
 
152
126
  def generate_unreleased_section
153
127
  log = ""
154
- if @options[:unreleased]
155
- unreleased_log = generate_log_between_tags(filtered_tags[0], nil)
156
- log += unreleased_log if unreleased_log
128
+ if options[:unreleased]
129
+ start_tag = filtered_tags[0] || sorted_tags.last
130
+ unreleased_log = generate_log_between_tags(start_tag, nil)
131
+ log += unreleased_log if unreleased_log
157
132
  end
158
133
  log
159
134
  end
@@ -166,24 +141,36 @@ module GitHubChangelogGenerator
166
141
  # @param [Hash] issue Fetched issue from GitHub
167
142
  # @return [String] Markdown-formatted single issue
168
143
  def get_string_for_issue(issue)
169
- encapsulated_title = encapsulate_string issue[:title]
144
+ encapsulated_title = encapsulate_string issue["title"]
170
145
 
171
- title_with_number = "#{encapsulated_title} [\\##{issue[:number]}](#{issue.html_url})"
146
+ title_with_number = "#{encapsulated_title} [\\##{issue['number']}](#{issue['html_url']})"
147
+ if options[:issue_line_labels].present?
148
+ title_with_number = "#{title_with_number}#{line_labels_for(issue)}"
149
+ end
172
150
  issue_line_with_user(title_with_number, issue)
173
151
  end
174
152
 
175
153
  private
176
154
 
155
+ def line_labels_for(issue)
156
+ labels = if options[:issue_line_labels] == ["ALL"]
157
+ issue["labels"]
158
+ else
159
+ issue["labels"].select { |label| options[:issue_line_labels].include?(label["name"]) }
160
+ end
161
+ labels.map { |label| " \[[#{label['name']}](#{label['url'].sub('api.github.com/repos', 'github.com')})\]" }.join("")
162
+ end
163
+
177
164
  def issue_line_with_user(line, issue)
178
- return line if !@options[:author] || issue.pull_request.nil?
165
+ return line if !options[:author] || issue["pull_request"].nil?
179
166
 
180
- user = issue.user
167
+ user = issue["user"]
181
168
  return "#{line} ({Null user})" unless user
182
169
 
183
- if @options[:usernames_as_github_logins]
184
- "#{line} (@#{user.login})"
170
+ if options[:usernames_as_github_logins]
171
+ "#{line} (@#{user['login']})"
185
172
  else
186
- "#{line} ([#{user.login}](#{user.html_url}))"
173
+ "#{line} ([#{user['login']}](#{user['html_url']}))"
187
174
  end
188
175
  end
189
176
  end
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
  module GitHubChangelogGenerator
3
3
  class Generator
4
- # delete all labels with labels from @options[:exclude_labels] array
4
+ # delete all labels with labels from options[:exclude_labels] array
5
5
  # @param [Array] issues
6
6
  # @return [Array] filtered array
7
7
  def exclude_issues_by_labels(issues)
8
- return issues if !@options[:exclude_labels] || @options[:exclude_labels].empty?
8
+ return issues if !options[:exclude_labels] || options[:exclude_labels].empty?
9
9
 
10
10
  issues.reject do |issue|
11
- labels = issue.labels.map(&:name)
12
- (labels & @options[:exclude_labels]).any?
11
+ labels = issue["labels"].map { |l| l["name"] }
12
+ (labels & options[:exclude_labels]).any?
13
13
  end
14
14
  end
15
15
 
@@ -32,18 +32,18 @@ module GitHubChangelogGenerator
32
32
  # @return [Array] issues with milestone #tag_name
33
33
  def find_issues_to_add(all_issues, tag_name)
34
34
  all_issues.select do |issue|
35
- if issue.milestone.nil?
35
+ if issue["milestone"].nil?
36
36
  false
37
37
  else
38
38
  # check, that this milestone in tag list:
39
39
  milestone_is_tag = @filtered_tags.find do |tag|
40
- tag.name == issue.milestone.title
40
+ tag["name"] == issue["milestone"]["title"]
41
41
  end
42
42
 
43
43
  if milestone_is_tag.nil?
44
44
  false
45
45
  else
46
- issue.milestone.title == tag_name
46
+ issue["milestone"]["title"] == tag_name
47
47
  end
48
48
  end
49
49
  end
@@ -53,11 +53,11 @@ module GitHubChangelogGenerator
53
53
  def remove_issues_in_milestones(filtered_issues)
54
54
  filtered_issues.select! do |issue|
55
55
  # leave issues without milestones
56
- if issue.milestone.nil?
56
+ if issue["milestone"].nil?
57
57
  true
58
58
  else
59
59
  # check, that this milestone in tag list:
60
- @filtered_tags.find { |tag| tag.name == issue.milestone.title }.nil?
60
+ @filtered_tags.find { |tag| tag["name"] == issue["milestone"]["title"] }.nil?
61
61
  end
62
62
  end
63
63
  end
@@ -68,16 +68,18 @@ module GitHubChangelogGenerator
68
68
  # @param [String] older_tag all issues before this tag date will be excluded. May be nil, if it's first tag
69
69
  # @param [String] newer_tag all issue after this tag will be excluded. May be nil for unreleased section
70
70
  # @return [Array] filtered issues
71
- def delete_by_time(issues, hash_key = :actual_date, older_tag = nil, newer_tag = nil)
71
+ def delete_by_time(issues, hash_key = "actual_date", older_tag = nil, newer_tag = nil)
72
72
  # in case if not tags specified - return unchanged array
73
73
  return issues if older_tag.nil? && newer_tag.nil?
74
74
 
75
+ older_tag = ensure_older_tag(older_tag, newer_tag)
76
+
75
77
  newer_tag_time = newer_tag && get_time_of_tag(newer_tag)
76
78
  older_tag_time = older_tag && get_time_of_tag(older_tag)
77
79
 
78
80
  issues.select do |issue|
79
81
  if issue[hash_key]
80
- time = Time.parse(issue[hash_key]).utc
82
+ time = Time.parse(issue[hash_key].to_s).utc
81
83
 
82
84
  tag_in_range_old = tag_newer_old_tag?(older_tag_time, time)
83
85
 
@@ -92,6 +94,14 @@ module GitHubChangelogGenerator
92
94
  end
93
95
  end
94
96
 
97
+ def ensure_older_tag(older_tag, newer_tag)
98
+ return older_tag if older_tag
99
+ idx = sorted_tags.index { |t| t["name"] == newer_tag["name"] }
100
+ # skip if we are already at the oldest element
101
+ return if idx == sorted_tags.size - 1
102
+ sorted_tags[idx - 1]
103
+ end
104
+
95
105
  def tag_older_new_tag?(newer_tag_time, time)
96
106
  tag_in_range_new = if newer_tag_time.nil?
97
107
  true
@@ -121,9 +131,9 @@ module GitHubChangelogGenerator
121
131
 
122
132
  # @return [Array] issues without labels or empty array if add_issues_wo_labels is false
123
133
  def filter_wo_labels(issues)
124
- if @options[:add_issues_wo_labels]
134
+ if options[:add_issues_wo_labels]
125
135
  issues_wo_labels = issues.select do |issue|
126
- !issue.labels.map(&:name).any?
136
+ !issue["labels"].map { |l| l["name"] }.any?
127
137
  end
128
138
  return issues_wo_labels
129
139
  end
@@ -131,11 +141,11 @@ module GitHubChangelogGenerator
131
141
  end
132
142
 
133
143
  def filter_by_include_labels(issues)
134
- if @options[:include_labels].nil?
144
+ if options[:include_labels].nil?
135
145
  issues
136
146
  else
137
147
  issues.select do |issue|
138
- labels = issue.labels.map(&:name) & @options[:include_labels]
148
+ labels = issue["labels"].map { |l| l["name"] } & options[:include_labels]
139
149
  labels.any?
140
150
  end
141
151
  end
@@ -154,18 +164,18 @@ module GitHubChangelogGenerator
154
164
  # @return [Array] Filtered issues
155
165
  def get_filtered_issues(issues)
156
166
  issues = filter_array_by_labels(issues)
157
- puts "Filtered issues: #{issues.count}" if @options[:verbose]
167
+ puts "Filtered issues: #{issues.count}" if options[:verbose]
158
168
  issues
159
169
  end
160
170
 
161
171
  # This method fetches missing params for PR and filter them by specified options
162
- # It include add all PR's with labels from @options[:include_labels] array
172
+ # It include add all PR's with labels from options[:include_labels] array
163
173
  # And exclude all from :exclude_labels array.
164
174
  # @return [Array] filtered PR's
165
175
  def get_filtered_pull_requests(pull_requests)
166
176
  pull_requests = filter_array_by_labels(pull_requests)
167
177
  pull_requests = filter_merged_pull_requests(pull_requests)
168
- puts "Filtered pull requests: #{pull_requests.count}" if @options[:verbose]
178
+ puts "Filtered pull requests: #{pull_requests.count}" if options[:verbose]
169
179
  pull_requests
170
180
  end
171
181
 
@@ -174,21 +184,21 @@ module GitHubChangelogGenerator
174
184
  # :merged_at - is a date, when issue PR was merged.
175
185
  # More correct to use merged date, rather than closed date.
176
186
  def filter_merged_pull_requests(pull_requests)
177
- print "Fetching merged dates...\r" if @options[:verbose]
187
+ print "Fetching merged dates...\r" if options[:verbose]
178
188
  closed_pull_requests = @fetcher.fetch_closed_pull_requests
179
189
 
180
190
  pull_requests.each do |pr|
181
191
  fetched_pr = closed_pull_requests.find do |fpr|
182
- fpr.number == pr.number
192
+ fpr["number"] == pr["number"]
183
193
  end
184
194
  if fetched_pr
185
- pr[:merged_at] = fetched_pr[:merged_at]
195
+ pr["merged_at"] = fetched_pr["merged_at"]
186
196
  closed_pull_requests.delete(fetched_pr)
187
197
  end
188
198
  end
189
199
 
190
200
  pull_requests.select! do |pr|
191
- !pr[:merged_at].nil?
201
+ !pr["merged_at"].nil?
192
202
  end
193
203
 
194
204
  pull_requests