diff --git a/lib/CHANGELOG.md b/lib/CHANGELOG.md index 745eb59..a261d8f 100644 --- a/lib/CHANGELOG.md +++ b/lib/CHANGELOG.md @@ -6,8 +6,6 @@ **Merged pull requests:** -- This PR SHOULD NOT appear in change log! [\#6](https://github.com/skywinder/changelog_test/pull/6) ([skywinder](https://github.com/skywinder)) - - Add automatically generated change log file. [\#5](https://github.com/skywinder/changelog_test/pull/5) ([skywinder](https://github.com/skywinder)) ## [v0.0.3](https://github.com/skywinder/changelog_test/tree/v0.0.3) (2015-03-04) diff --git a/lib/github_changelog_generator.rb b/lib/github_changelog_generator.rb index ea7576c..8a02b9a 100755 --- a/lib/github_changelog_generator.rb +++ b/lib/github_changelog_generator.rb @@ -32,7 +32,8 @@ module GitHubChangelogGenerator # @all_tags = get_filtered_tags @all_tags = @fetcher.get_all_tags - @issues, @pull_requests = @fetcher.fetch_issues_and_pull_requests + # TODO: refactor this double asssign of @issues and @pull_requests and move all logic in one method + @issues, @pull_requests = @fetcher.fetch_closed_issues_and_pr @pull_requests = @options[:pulls] ? get_filtered_pull_requests : [] @@ -120,7 +121,7 @@ module GitHubChangelogGenerator # And exclude all from :exclude_labels array. # @return [Array] filtered PR's def get_filtered_pull_requests - fetch_merged_at_pull_requests + filter_merged_pull_requests filtered_pull_requests = include_issues_by_labels(@pull_requests) @@ -133,14 +134,15 @@ module GitHubChangelogGenerator filtered_pull_requests end - # This method fetch missing required attributes for pull requests + # This method filter only merged PR and + # 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. - def fetch_merged_at_pull_requests + # More correct to use merged date, rather than closed date. + def filter_merged_pull_requests if @options[:verbose] print "Fetching merged dates...\r" end - pull_requests = @fetcher.fetch_pull_requests + pull_requests = @fetcher.fetch_closed_pull_requests @pull_requests.each { |pr| fetched_pr = pull_requests.find { |fpr| @@ -150,8 +152,8 @@ module GitHubChangelogGenerator pull_requests.delete(fetched_pr) } - if @options[:verbose] - puts "Fetching merged dates: Done!" + @pull_requests.select! do |pr| + !pr[:merged_at].nil? end end @@ -217,7 +219,7 @@ module GitHubChangelogGenerator output_filename = "#{@options[:output]}" File.open(output_filename, "w") { |file| file.write(log) } puts "Done!" - puts "Generated log placed in #{`pwd`.strip!}/#{output_filename}" + puts "Generated log placed in #{Dir.pwd}/#{output_filename}" end # The full cycle of generation for whole project @@ -279,7 +281,7 @@ module GitHubChangelogGenerator threads.each(&:join) if @options[:verbose] - puts "Fetching tags dates: #{i} Done!" + puts "Fetching tags dates: #{i}" end end diff --git a/lib/github_changelog_generator/fetcher.rb b/lib/github_changelog_generator/fetcher.rb index e5d451c..863a422 100644 --- a/lib/github_changelog_generator/fetcher.rb +++ b/lib/github_changelog_generator/fetcher.rb @@ -9,8 +9,10 @@ module GitHubChangelogGenerator class Fetcher PER_PAGE_NUMBER = 30 CHANGELOG_GITHUB_TOKEN = "CHANGELOG_GITHUB_TOKEN" - GH_RATE_LIMIT_EXCEEDED_MSG = "Warning: GitHub API rate limit (5000 per hour) exceeded, change log may be " \ - "missing some issues. You can limit the number of issues fetched using the `--max-issues NUM` argument." + GH_RATE_LIMIT_EXCEEDED_MSG = "Warning: Can't finish operation: GitHub API rate limit exceeded, change log may be " \ + "missing some issues. You can limit the number of issues fetched using the `--max-issues NUM` argument." + NO_TOKEN_PROVIDED = "Warning: No token provided (-t option) and variable $CHANGELOG_GITHUB_TOKEN was not found. " \ + "This script can make only 50 requests to GitHub API per hour without token!" def initialize(options = {}) @options = options @@ -29,11 +31,7 @@ module GitHubChangelogGenerator github_options[:endpoint] = options[:github_endpoint] unless options[:github_endpoint].nil? github_options[:site] = options[:github_endpoint] unless options[:github_site].nil? - begin - @github = Github.new github_options - rescue - @logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow - end + @github = check_github_response { Github.new github_options } end # Returns GitHub token. First try to use variable, provided by --token option, @@ -44,8 +42,7 @@ module GitHubChangelogGenerator env_var = @options[:token] ? @options[:token] : (ENV.fetch CHANGELOG_GITHUB_TOKEN, nil) unless env_var - @logger.warn "Warning: No token provided (-t option) and variable $CHANGELOG_GITHUB_TOKEN was not found.".yellow - @logger.warn "This script can make only 50 requests to GitHub API per hour without token!".yellow + @logger.warn NO_TOKEN_PROVIDED.yellow end env_var @@ -60,35 +57,47 @@ module GitHubChangelogGenerator tags = [] - begin - response = @github.repos.tags @options[:user], @options[:project] - page_i = 0 - count_pages = response.count_pages - response.each_page do |page| - page_i += PER_PAGE_NUMBER - print "Fetching tags... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r" - tags.concat(page) - end - print " \r" - - if tags.count == 0 - @logger.warn "Warning: Can't find any tags in repo.\ -Make sure, that you push tags to remote repo via 'git push --tags'".yellow - elsif @options[:verbose] - @logger.info "Found #{tags.count} tags" - end - - rescue - @logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow - end + check_github_response { github_fetch_tags(tags) } tags end + def check_github_response + begin + value = yield + rescue Github::Error::Unauthorized => e + @logger.error e.body.red + abort "Error: wrong GitHub token" + rescue Github::Error::Forbidden => e + @logger.warn e.body.red + @logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow + end + value + end + + def github_fetch_tags(tags) + response = @github.repos.tags @options[:user], @options[:project] + page_i = 0 + count_pages = response.count_pages + response.each_page do |page| + page_i += PER_PAGE_NUMBER + print_in_same_line("Fetching tags... #{page_i}/#{count_pages * PER_PAGE_NUMBER}") + tags.concat(page) + end + print_empty_line + + if tags.count == 0 + @logger.warn "Warning: Can't find any tags in repo.\ +Make sure, that you push tags to remote repo via 'git push --tags'".yellow + else + @logger.info "Found #{tags.count} tags" + end + end + # This method fetch all closed issues and separate them to pull requests and pure issues # (pull request is kind of issue in term of GitHub) - # @return [Tuple] with issues and pull requests - def fetch_issues_and_pull_requests + # @return [Tuple] with (issues, pull-requests) + def fetch_closed_issues_and_pr if @options[:verbose] print "Fetching closed issues...\r" end @@ -104,21 +113,18 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow count_pages = response.count_pages response.each_page do |page| page_i += PER_PAGE_NUMBER - print "Fetching issues... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r" + print_in_same_line("Fetching issues... #{page_i}/#{count_pages * PER_PAGE_NUMBER}") issues.concat(page) break if @options[:max_issues] && issues.length >= @options[:max_issues] end + print_empty_line + @logger.info "Received issues: #{issues.count}" + rescue @logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow end - print " \r" - - if @options[:verbose] - @logger.info "Received issues: #{issues.count}" - end - - # remove pull request from issues: + # separate arrays of issues and pull requests: issues.partition do |x| x[:pull_request].nil? end @@ -126,25 +132,35 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow # Fetch all pull requests. We need them to detect :merged_at parameter # @return [Array] all pull requests - def fetch_pull_requests + def fetch_closed_pull_requests pull_requests = [] begin response = @github.pull_requests.list @options[:user], @options[:project], state: "closed" page_i = 0 + count_pages = response.count_pages response.each_page do |page| page_i += PER_PAGE_NUMBER - count_pages = response.count_pages - print "Fetching merged dates... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r" + log_string = "Fetching merged dates... #{page_i}/#{count_pages * PER_PAGE_NUMBER}" + print_in_same_line(log_string) pull_requests.concat(page) end + print_empty_line rescue @logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow end - print " \r" + @logger.info "Fetching merged dates: #{pull_requests.count}" pull_requests end + def print_in_same_line(log_string) + print log_string + "\r" + end + + def print_empty_line + print_in_same_line(" ") + end + # Fetch event for all issues and add them to :events # @param [Array] issues # @return [Void] @@ -163,7 +179,7 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow @logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow end issue[:events] = obj.body - print "Fetching events for issues and PR: #{i + 1}/#{issues.count}\r" + print_in_same_line("Fetching events for issues and PR: #{i + 1}/#{issues.count}") i += 1 end end @@ -172,11 +188,9 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow end # to clear line from prev print - print " \r" + print_empty_line - if @options[:verbose] - @logger.info "Fetching events for issues and PR: #{i} Done!" - end + @logger.info "Fetching events for issues and PR: #{i}" end # Try to find tag date in local hash. diff --git a/lib/github_changelog_generator/version.rb b/lib/github_changelog_generator/version.rb index 8ec937b..65eb6cc 100644 --- a/lib/github_changelog_generator/version.rb +++ b/lib/github_changelog_generator/version.rb @@ -1,3 +1,3 @@ module GitHubChangelogGenerator - VERSION = "1.4.0" + VERSION = "1.4.1" end diff --git a/spec/unit/fetcher_spec.rb b/spec/unit/fetcher_spec.rb index 709563f..6baf815 100644 --- a/spec/unit/fetcher_spec.rb +++ b/spec/unit/fetcher_spec.rb @@ -1,5 +1,16 @@ +VALID_TOKEN = "0123456789abcdef" +INVALID_TOKEN = "0000000000000000" + +DEFAULT_OPTIONS = { user: "skywinder", + project: "changelog_test" } + +def options_with_invalid_token + options = DEFAULT_OPTIONS + options[:token] = INVALID_TOKEN + options +end + describe GitHubChangelogGenerator::Fetcher do - VALID_TOKEN = "0123456789abcdef" before(:all) do @fetcher = GitHubChangelogGenerator::Fetcher.new end @@ -33,4 +44,16 @@ describe GitHubChangelogGenerator::Fetcher do it { is_expected.to eq(VALID_TOKEN) } end end + + describe "#github_fetch_tags" do + context "when wrong token provided" do + before do + options = options_with_invalid_token + @fetcher = GitHubChangelogGenerator::Fetcher.new(options) + end + it "should raise Unauthorized error" do + expect { @fetcher.github_fetch_tags [] }.to raise_error Github::Error::Unauthorized + end + end + end end