Class: GitHubChangelogGenerator::ChangelogGenerator
- Inherits:
-
Object
- Object
- GitHubChangelogGenerator::ChangelogGenerator
- Defined in:
- lib/github_changelog_generator.rb
Overview
Main class and entry point for this script.
Instance Attribute Summary collapse
-
#all_tags ⇒ Object
Returns the value of attribute all_tags.
-
#github ⇒ Object
Returns the value of attribute github.
-
#options ⇒ Object
Returns the value of attribute options.
Instance Method Summary collapse
-
#compound_changelog ⇒ Object
The entry point of this script to generate change log.
-
#create_log(pull_requests, issues, newer_tag, older_tag_name = nil) ⇒ String
Generates log for section with header and body.
-
#delete_by_time(array, hash_key = :actual_date, older_tag = nil, newer_tag = nil) ⇒ Array
Method filter issues, that belong only specified tag range.
- #detect_actual_closed_dates ⇒ Object
-
#exclude_issues_by_labels(issues) ⇒ Array
delete all labels with labels from @options array.
-
#fetch_event_for_issues_and_pr ⇒ Array
Fetch event for issues and pull requests.
-
#fetch_merged_at_pull_requests ⇒ Object
This method fetch missing required attributes for pull requests :merged_at - is a date, when issue PR was merged.
-
#fetch_tags_dates ⇒ Object
Async fetching of all tags dates.
- #filter_by_milestone(filtered_issues, newer_tag_name, src_array) ⇒ Object
-
#find_closed_date_by_commit(issue) ⇒ Object
Fill :actual_date parameter of specified issue by closed date of the commit, it it was closed by commit.
-
#generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_link, project_url) ⇒ String
It generate one header for section with specific parameters.
-
#generate_log_between_tags(older_tag, newer_tag) ⇒ Object
Generate log only between 2 specified tags.
-
#generate_log_for_all_tags ⇒ String
The full cycle of generation for whole project.
-
#generate_sub_section(issues, prefix) ⇒ String
Generate ready-to-go sub-section.
-
#get_filtered_issues ⇒ Array
Filter issues according labels.
-
#get_filtered_pull_requests ⇒ Array
This method fetches missing params for PR and filter them by specified options It include add all PR’s with labels from @options array And exclude all from :exclude_labels array.
-
#get_filtered_tags ⇒ Array
Return tags after filtering tags in lists provided by option: –between-tags & –exclude-tags.
-
#include_issues_by_labels(issues) ⇒ Array
Include issues with labels, specified in :include_labels.
-
#initialize ⇒ Object
constructor
Class, responsible for whole change log generation cycle.
- #print_json(json) ⇒ Object
Constructor Details
#initialize ⇒ Object
Class, responsible for whole change log generation cycle
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/github_changelog_generator.rb', line 25 def initialize @options = Parser. @fetcher = GitHubChangelogGenerator::Fetcher.new @options @generator = Generator.new @options # @all_tags = get_filtered_tags @all_tags = @fetcher. @issues, @pull_requests = @fetcher.fetch_issues_and_pull_requests @pull_requests = @options[:pulls] ? get_filtered_pull_requests : [] @issues = @options[:issues] ? get_filtered_issues : [] fetch_event_for_issues_and_pr detect_actual_closed_dates end |
Instance Attribute Details
#all_tags ⇒ Object
Returns the value of attribute all_tags.
21 22 23 |
# File 'lib/github_changelog_generator.rb', line 21 def @all_tags end |
#github ⇒ Object
Returns the value of attribute github.
21 22 23 |
# File 'lib/github_changelog_generator.rb', line 21 def github @github end |
#options ⇒ Object
Returns the value of attribute options.
21 22 23 |
# File 'lib/github_changelog_generator.rb', line 21 def @options end |
Instance Method Details
#compound_changelog ⇒ Object
The entry point of this script to generate change log
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/github_changelog_generator.rb', line 187 def compound_changelog log = "# Change Log\n\n" if @options[:unreleased_only] log += ([0], nil) elsif @options[:tag1] and @options[:tag2] tag1 = @options[:tag1] tag2 = @options[:tag2] = [] .each { |x| .push(x["name"]) } if .include?(tag1) if .include?(tag2) to_a = .map.with_index.to_a hash = Hash[to_a] index1 = hash[tag1] index2 = hash[tag2] log += ([index1], [index2]) else fail ChangelogGeneratorError, "Can't find tag #{tag2} -> exit".red end else fail ChangelogGeneratorError, "Can't find tag #{tag1} -> exit".red end else log += end log += "\n\n\\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*" output_filename = "#{@options[:output]}" File.open(output_filename, "w") { |file| file.write(log) } puts "Done!" puts "Generated log placed in #{`pwd`.strip!}/#{output_filename}" end |
#create_log(pull_requests, issues, newer_tag, older_tag_name = nil) ⇒ String
Generates log for section with header and body
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/github_changelog_generator.rb', line 389 def create_log(pull_requests, issues, newer_tag, older_tag_name = nil) newer_tag_time = newer_tag.nil? ? Time.new : @fetcher.get_time_of_tag(newer_tag) newer_tag_name = newer_tag.nil? ? @options[:unreleased_label] : newer_tag["name"] newer_tag_link = newer_tag.nil? ? "HEAD" : newer_tag_name github_site = [:github_site] || "https://github.com" project_url = "#{github_site}/#{@options[:user]}/#{@options[:project]}" log = generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_name, project_url) if @options[:issues] # Generate issues: issues_a = [] enhancement_a = [] bugs_a = [] issues.each { |dict| added = false dict.labels.each { |label| if label.name == "bug" bugs_a.push dict added = true next end if label.name == "enhancement" enhancement_a.push dict added = true next end } unless added issues_a.push dict end } log += generate_sub_section(enhancement_a, @options[:enhancement_prefix]) log += generate_sub_section(bugs_a, @options[:bug_prefix]) log += generate_sub_section(issues_a, @options[:issue_prefix]) end if @options[:pulls] # Generate pull requests: log += generate_sub_section(pull_requests, @options[:merge_prefix]) end log end |
#delete_by_time(array, hash_key = :actual_date, older_tag = nil, newer_tag = nil) ⇒ Array
Method filter issues, that belong only specified tag range
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/github_changelog_generator.rb', line 351 def delete_by_time(array, hash_key = :actual_date, older_tag = nil, newer_tag = nil) fail ChangelogGeneratorError, "At least one of the tags should be not nil!".red if older_tag.nil? && newer_tag.nil? newer_tag_time = newer_tag && @fetcher.get_time_of_tag(newer_tag) older_tag_time = older_tag && @fetcher.get_time_of_tag(older_tag) array.select { |req| if req[hash_key] t = Time.parse(req[hash_key]).utc if older_tag_time.nil? tag_in_range_old = true else tag_in_range_old = t > older_tag_time end if newer_tag_time.nil? tag_in_range_new = true else tag_in_range_new = t <= newer_tag_time end tag_in_range = (tag_in_range_old) && (tag_in_range_new) tag_in_range else false end } end |
#detect_actual_closed_dates ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/github_changelog_generator.rb', line 62 def detect_actual_closed_dates if @options[:verbose] print "Fetching closed dates for issues...\r" end threads = [] @issues.each { |issue| threads << Thread.new { find_closed_date_by_commit(issue) } } @pull_requests.each { |pull_request| threads << Thread.new { find_closed_date_by_commit(pull_request) } } threads.each(&:join) if @options[:verbose] puts "Fetching closed dates for issues: Done!" end end |
#exclude_issues_by_labels(issues) ⇒ Array
delete all labels with labels from @options array
176 177 178 179 180 181 182 183 |
# File 'lib/github_changelog_generator.rb', line 176 def exclude_issues_by_labels(issues) unless @options[:exclude_labels].nil? issues = issues.select { |issue| !(issue.labels.map(&:name) & @options[:exclude_labels]).any? } end issues end |
#fetch_event_for_issues_and_pr ⇒ Array
Fetch event for issues and pull requests
501 502 503 504 505 506 507 508 509 |
# File 'lib/github_changelog_generator.rb', line 501 def fetch_event_for_issues_and_pr if @options[:verbose] print "Fetching events for issues and PR: 0/#{@issues.count + @pull_requests.count}\r" end # Async fetching events: @fetcher.fetch_events_async(@issues + @pull_requests) end |
#fetch_merged_at_pull_requests ⇒ Object
This method fetch missing required attributes for pull requests :merged_at - is a date, when issue PR was merged. More correct to use this date, not closed date.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/github_changelog_generator.rb', line 139 def fetch_merged_at_pull_requests if @options[:verbose] print "Fetching merged dates...\r" end pull_requests = @fetcher.fetch_pull_requests @pull_requests.each { |pr| fetched_pr = pull_requests.find { |fpr| fpr.number == pr.number } pr[:merged_at] = fetched_pr[:merged_at] pull_requests.delete(fetched_pr) } if @options[:verbose] puts "Fetching merged dates: Done!" end end |
#fetch_tags_dates ⇒ Object
Async fetching of all tags dates
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/github_changelog_generator.rb', line 258 def if @options[:verbose] print "Fetching tag dates...\r" end # Async fetching tags: threads = [] i = 0 all = @all_tags.count @all_tags.each { |tag| threads << Thread.new { @fetcher.get_time_of_tag(tag) if @options[:verbose] print "Fetching tags dates: #{i + 1}/#{all}\r" i += 1 end } } print " \r" threads.each(&:join) if @options[:verbose] puts "Fetching tags dates: #{i} Done!" end end |
#filter_by_milestone(filtered_issues, newer_tag_name, src_array) ⇒ Object
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
# File 'lib/github_changelog_generator.rb', line 310 def filter_by_milestone(filtered_issues, newer_tag_name, src_array) filtered_issues.select! { |issue| # leave issues without milestones if issue.milestone.nil? true else # check, that this milestone in tag list: @all_tags.find { |tag| tag.name == issue.milestone.title }.nil? end } unless newer_tag_name.nil? # add missed issues (according milestones) issues_to_add = src_array.select { |issue| if issue.milestone.nil? false else # check, that this milestone in tag list: milestone_is_tag = @all_tags.find { |tag| tag.name == issue.milestone.title } if milestone_is_tag.nil? false else issue.milestone.title == newer_tag_name end end } filtered_issues |= issues_to_add end filtered_issues end |
#find_closed_date_by_commit(issue) ⇒ Object
Fill :actual_date parameter of specified issue by closed date of the commit, it it was closed by commit.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/github_changelog_generator.rb', line 89 def find_closed_date_by_commit(issue) unless issue["events"].nil? # if it's PR -> then find "merged event", in case of usual issue -> fond closed date compare_string = issue[:merged_at].nil? ? "closed" : "merged" # reverse! - to find latest closed event. (event goes in date order) issue["events"].reverse!.each { |event| if event[:event].eql? compare_string if event[:commit_id].nil? issue[:actual_date] = issue[:closed_at] else begin commit = @fetcher.fetch_commit(event) issue[:actual_date] = commit[:author][:date] rescue puts "Warning: Can't fetch commit #{event[:commit_id]}. It is probably referenced from another repo.".yellow issue[:actual_date] = issue[:closed_at] end end break end } end # TODO: assert issues, that remain without 'actual_date' hash for some reason. end |
#generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_link, project_url) ⇒ String
It generate one header for section with specific parameters.
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 |
# File 'lib/github_changelog_generator.rb', line 464 def generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_link, project_url) log = "" # Generate date string: time_string = newer_tag_time.strftime @options[:dateformat] # Generate tag name and link if newer_tag_name.equal? @options[:unreleased_label] log += "## [#{newer_tag_name}](#{project_url}/tree/#{newer_tag_link})\n\n" else log += "## [#{newer_tag_name}](#{project_url}/tree/#{newer_tag_link}) (#{time_string})\n\n" end if @options[:compare_link] && older_tag_link # Generate compare link log += "[Full Changelog](#{project_url}/compare/#{older_tag_link}...#{newer_tag_link})\n\n" end log end |
#generate_log_between_tags(older_tag, newer_tag) ⇒ Object
Generate log only between 2 specified tags
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/github_changelog_generator.rb', line 289 def (older_tag, newer_tag) filtered_pull_requests = delete_by_time(@pull_requests, :actual_date, older_tag, newer_tag) filtered_issues = delete_by_time(@issues, :actual_date, older_tag, newer_tag) newer_tag_name = newer_tag.nil? ? nil : newer_tag["name"] older_tag_name = older_tag.nil? ? nil : older_tag["name"] if @options[:filter_issues_by_milestone] # delete excess irrelevant issues (according milestones) filtered_issues = filter_by_milestone(filtered_issues, newer_tag_name, @issues) filtered_pull_requests = filter_by_milestone(filtered_pull_requests, newer_tag_name, @pull_requests) end if filtered_issues.empty? && filtered_pull_requests.empty? && newer_tag.nil? # do not generate empty unreleased section return "" end create_log(filtered_pull_requests, filtered_issues, newer_tag, older_tag_name) end |
#generate_log_for_all_tags ⇒ String
The full cycle of generation for whole project
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/github_changelog_generator.rb', line 225 def if @options[:verbose] puts "Sorting tags..." end @all_tags.sort_by! { |x| @fetcher.get_time_of_tag(x) }.reverse! if @options[:verbose] puts "Generating log..." end log = "" if @options[:unreleased] && @all_tags.count != 0 unreleased_log = ([0], nil) if unreleased_log log += unreleased_log end end (1....size).each { |index| log += ([index], [index - 1]) } if @all_tags.count != 0 log += (nil, .last) end log end |
#generate_sub_section(issues, prefix) ⇒ String
Returns Generate ready-to-go sub-section.
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 |
# File 'lib/github_changelog_generator.rb', line 440 def generate_sub_section(issues, prefix) log = "" if [:simple_list] != true && issues.any? log += "#{prefix}\n\n" end if issues.any? issues.each { |issue| merge_string = @generator.get_string_for_issue(issue) log += "- #{merge_string}\n\n" } end log end |
#get_filtered_issues ⇒ Array
Filter issues according labels
487 488 489 490 491 492 493 494 495 496 497 |
# File 'lib/github_changelog_generator.rb', line 487 def get_filtered_issues filtered_issues = include_issues_by_labels(@issues) filtered_issues = exclude_issues_by_labels(filtered_issues) if @options[:verbose] puts "Filtered issues: #{filtered_issues.count}" end filtered_issues end |
#get_filtered_pull_requests ⇒ Array
This method fetches missing params for PR and filter them by specified options It include add all PR’s with labels from @options array And exclude all from :exclude_labels array.
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/github_changelog_generator.rb', line 122 def get_filtered_pull_requests fetch_merged_at_pull_requests filtered_pull_requests = include_issues_by_labels(@pull_requests) filtered_pull_requests = exclude_issues_by_labels(filtered_pull_requests) if @options[:verbose] puts "Filtered pull requests: #{filtered_pull_requests.count}" end filtered_pull_requests end |
#get_filtered_tags ⇒ Array
Return tags after filtering tags in lists provided by option: –between-tags & –exclude-tags
48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/github_changelog_generator.rb', line 48 def = @fetcher. = [] if @options[:between_tags] @options[:between_tags].each do |tag| unless .include? tag puts "Warning: can't find tag #{tag}, specified with --between-tags option.".yellow end end = .select { |tag| @options[:between_tags].include? tag } end end |
#include_issues_by_labels(issues) ⇒ Array
Include issues with labels, specified in :include_labels
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/github_changelog_generator.rb', line 161 def include_issues_by_labels(issues) filtered_issues = @options[:include_labels].nil? ? issues : issues.select { |issue| (issue.labels.map(&:name) & @options[:include_labels]).any? } if @options[:add_issues_wo_labels] issues_wo_labels = issues.select { |issue| !issue.labels.map(&:name).any? } filtered_issues |= issues_wo_labels end filtered_issues end |
#print_json(json) ⇒ Object
114 115 116 |
# File 'lib/github_changelog_generator.rb', line 114 def print_json(json) puts JSON.pretty_generate(json) end |