From a9baa37c64a5b253274322e5ca908753002cf8fa Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Thu, 26 Mar 2015 11:48:06 +0200 Subject: [PATCH 1/8] add rspec init files --- .rspec | 2 + spec/spec_helper.rb | 91 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 .rspec create mode 100644 spec/spec_helper.rb diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..83e16f8 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--require spec_helper diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..b598abe --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,91 @@ +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # These two settings work together to allow you to limit a spec run + # to individual examples or groups you care about by tagging them with + # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # get run. + config.filter_run :focus + config.run_all_when_everything_filtered = true + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax + # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = 'doc' + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end From f48236e47bbc432b07d74900e687d03471bcd312 Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Thu, 26 Mar 2015 12:34:41 +0200 Subject: [PATCH 2/8] change default configs --- spec/spec_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b598abe..b21a3f5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -55,7 +55,7 @@ RSpec.configure do |config| # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching - config.disable_monkey_patching! + # config.disable_monkey_patching! # This setting enables warnings. It's recommended, but in some cases may # be too noisy due to issues in dependencies. @@ -74,7 +74,7 @@ RSpec.configure do |config| # Print the 10 slowest examples and example groups at the # end of the spec run, to help surface which specs are running # particularly slow. - config.profile_examples = 10 + # config.profile_examples = 10 # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing From a09b6affd47b4853807cb0f12d73a148027e6ea8 Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Thu, 26 Mar 2015 15:33:56 +0200 Subject: [PATCH 3/8] add rubocop and rspec to Rakefile --- Rakefile | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Rakefile b/Rakefile index b5ce9ca..0cdc203 100644 --- a/Rakefile +++ b/Rakefile @@ -1,9 +1,8 @@ -require "rake/testtask" +require 'rubocop/rake_task' +require 'rspec/core/rake_task' -task :default => [:test] +RuboCop::RakeTask.new +RSpec::Core::RakeTask.new(:rspec) + +task :default => [:rubocop, :rspec] -Rake::TestTask.new do |t| - t.verbose = true - t.libs.push("demo", "test") - t.pattern = "test/**/*_test.rb" -end From cca8e5d810d4b4093ae5fd4e22935c6f8f44840e Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Thu, 26 Mar 2015 15:43:47 +0200 Subject: [PATCH 4/8] rubocop auto-fixes --- Rakefile | 3 +- bin/github_changelog_generator | 2 +- bump_gemfile.rb | 44 +++--- github_changelog_generator.gemspec | 27 ++-- lib/github_changelog_generator.rb | 151 ++++++++------------ lib/github_changelog_generator/generator.rb | 14 +- lib/github_changelog_generator/parser.rb | 59 ++++---- spec/spec_helper.rb | 24 +++- 8 files changed, 149 insertions(+), 175 deletions(-) diff --git a/Rakefile b/Rakefile index 0cdc203..3cc4800 100644 --- a/Rakefile +++ b/Rakefile @@ -4,5 +4,4 @@ require 'rspec/core/rake_task' RuboCop::RakeTask.new RSpec::Core::RakeTask.new(:rspec) -task :default => [:rubocop, :rspec] - +task default: [:rubocop, :rspec] diff --git a/bin/github_changelog_generator b/bin/github_changelog_generator index 591db33..3777a19 100755 --- a/bin/github_changelog_generator +++ b/bin/github_changelog_generator @@ -1,4 +1,4 @@ #! /usr/bin/env ruby require_relative '../lib/github_changelog_generator' -GitHubChangelogGenerator::ChangelogGenerator.new.compund_changelog \ No newline at end of file +GitHubChangelogGenerator::ChangelogGenerator.new.compund_changelog diff --git a/bump_gemfile.rb b/bump_gemfile.rb index 9705a91..8847817 100755 --- a/bump_gemfile.rb +++ b/bump_gemfile.rb @@ -7,7 +7,7 @@ SPEC_TYPE = 'gemspec' :minor :patch -@options = {:dry_run => false, :bump_number => :patch} +@options = { dry_run: false, bump_number: :patch } OptionParser.new { |opts| opts.banner = 'Usage: bump.rb [options]' @@ -15,13 +15,13 @@ OptionParser.new { |opts| opts.on('-d', '--dry-run', 'Dry run') do |v| @options[:dry_run] = v end - opts.on('-a', '--major', 'Bump major version') do |v| + opts.on('-a', '--major', 'Bump major version') do |_v| @options[:bump_number] = :major end - opts.on('-m', '--minor', 'Bump minor version') do |v| + opts.on('-m', '--minor', 'Bump minor version') do |_v| @options[:bump_number] = :minor end - opts.on('-p', '--patch', 'Bump patch version') do |v| + opts.on('-p', '--patch', 'Bump patch version') do |_v| @options[:bump_number] = :patch end opts.on('-r', '--revert', 'Revert last bump') do |v| @@ -32,7 +32,7 @@ OptionParser.new { |opts| p @options def check_repo_is_clean_or_dry_run - value =%x[#{'git status --porcelain'}] + value = `#{'git status --porcelain'}` if value.empty? puts 'Repo is clean -> continue' @@ -46,7 +46,6 @@ def check_repo_is_clean_or_dry_run end end - def find_spec_file list_of_specs = execute_line("find . -name '*.#{SPEC_TYPE}'") arr = list_of_specs.split("\n") @@ -61,18 +60,17 @@ def find_spec_file spec_file = arr[0] else puts 'Which spec should be used?' - arr.each_with_index { |file, index| puts "#{index+1}. #{file}" } + arr.each_with_index { |file, index| puts "#{index + 1}. #{file}" } input_index = Integer(gets.chomp) - spec_file = arr[input_index-1] + spec_file = arr[input_index - 1] end - if spec_file == nil + if spec_file.nil? puts "Can't find specified spec file -> exit" exit end spec_file.sub('./', '') - end def find_current_gem_file @@ -89,24 +87,23 @@ def find_current_gem_file spec_file = arr[0] else puts 'Which spec should be used?' - arr.each_with_index { |file, index| puts "#{index+1}. #{file}" } + arr.each_with_index { |file, index| puts "#{index + 1}. #{file}" } input_index = Integer(gets.chomp) - spec_file = arr[input_index-1] + spec_file = arr[input_index - 1] end - if spec_file == nil + if spec_file.nil? puts "Can't find specified spec file -> exit" exit end spec_file.sub('./', '') - end def find_version_in_podspec(podspec) readme = File.read(podspec) - #try to find version in format 1.22.333 + # try to find version in format 1.22.333 re = /(\d+)\.(\d+)\.(\d+)/m match_result = re.match(readme) @@ -117,12 +114,12 @@ def find_version_in_podspec(podspec) end puts "Found version #{match_result[0]}" - return match_result[0], match_result.captures + [match_result[0], match_result.captures] end def bump_version(versions_array) bumped_result = versions_array.dup - bumped_result.map! { |x| x.to_i } + bumped_result.map!(&:to_i) case @options[:bump_number] when :major @@ -135,10 +132,9 @@ def bump_version(versions_array) when :patch bumped_result[2] += 1 else - raise('unknown bump_number') + fail('unknown bump_number') end - bumped_version = bumped_result.join('.') puts "Bump version: #{versions_array.join('.')} -> #{bumped_version}" bumped_version @@ -157,7 +153,7 @@ def execute_line_if_not_dry_run(line) nil else puts line - value = %x[#{line}] + value = `#{line}` puts value check_exit_status(value) value @@ -165,14 +161,13 @@ def execute_line_if_not_dry_run(line) end def check_exit_status(output) - if $?.exitstatus != 0 - puts "Output:\n#{output}\nExit status = #{$?.exitstatus} ->Terminate script." + if $CHILD_STATUS.exitstatus != 0 + puts "Output:\n#{output}\nExit status = #{$CHILD_STATUS.exitstatus} ->Terminate script." exit end end def run_bumping_script - check_repo_is_clean_or_dry_run spec_file = find_spec_file result, versions_array = find_version_in_podspec(spec_file) @@ -198,7 +193,6 @@ def run_bumping_script gem = find_current_gem_file execute_line_if_not_dry_run("gem push #{gem}") # execute_line_if_not_dry_run("pod trunk push #{spec_file}") - end def revert_last_bump @@ -216,7 +210,7 @@ def revert_last_bump execute_line_if_not_dry_run("git push --delete origin #{result}") end -if __FILE__ == $0 +if __FILE__ == $PROGRAM_NAME if @options[:revert] revert_last_bump diff --git a/github_changelog_generator.gemspec b/github_changelog_generator.gemspec index 2c8f77e..8452ee7 100644 --- a/github_changelog_generator.gemspec +++ b/github_changelog_generator.gemspec @@ -5,28 +5,27 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'github_changelog_generator/version' Gem::Specification.new do |spec| - spec.name = "github_changelog_generator" + spec.name = 'github_changelog_generator' spec.version = GitHubChangelogGenerator::VERSION - spec.default_executable = "github_changelog_generator" + spec.default_executable = 'github_changelog_generator' spec.required_ruby_version = '>= 1.9.3' - spec.authors = ["Petr Korolev"] - spec.email = %q{sky4winder+github_changelog_generator@gmail.com} + spec.authors = ['Petr Korolev'] + spec.email = 'sky4winder+github_changelog_generator@gmail.com' spec.date = `date +"%Y-%m-%d"`.strip! - spec.summary = %q{Script, that automatically generate changelog from your tags, issues, labels and pull requests.} - spec.description = %q{Changelog generation has never been so easy. Fully automate changelog generation - this gem generate change log file based on tags, issues and merged pull requests from Github issue tracker.} - spec.homepage = %q{https://github.com/skywinder/Github-Changelog-Generator} - spec.license = "MIT" + spec.summary = 'Script, that automatically generate changelog from your tags, issues, labels and pull requests.' + spec.description = 'Changelog generation has never been so easy. Fully automate changelog generation - this gem generate change log file based on tags, issues and merged pull requests from Github issue tracker.' + spec.homepage = 'https://github.com/skywinder/Github-Changelog-Generator' + spec.license = 'MIT' spec.files = `git ls-files -z`.split("\x0") spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) - spec.require_paths = ["lib"] + spec.require_paths = ['lib'] - spec.add_development_dependency "bundler", "~> 1.7" - spec.add_development_dependency "rake", "~> 10.0" - - spec.add_runtime_dependency(%q, ["~> 0.12"]) - spec.add_runtime_dependency(%q, ["~> 0.7"]) + spec.add_development_dependency 'bundler', '~> 1.7' + spec.add_development_dependency 'rake', '~> 10.0' + spec.add_runtime_dependency('github_api', ['~> 0.12']) + spec.add_runtime_dependency('colorize', ['~> 0.7']) end diff --git a/lib/github_changelog_generator.rb b/lib/github_changelog_generator.rb index edfca96..a57226d 100755 --- a/lib/github_changelog_generator.rb +++ b/lib/github_changelog_generator.rb @@ -11,20 +11,18 @@ require_relative 'github_changelog_generator/version' module GitHubChangelogGenerator class ChangelogGenerator - attr_accessor :options, :all_tags, :github PER_PAGE_NUMBER = 30 - GH_RATE_LIMIT_EXCEEDED_MSG = 'Warning: GitHub API rate limit exceed (5000 per hour), change log may not ' + + GH_RATE_LIMIT_EXCEEDED_MSG = 'Warning: GitHub API rate limit exceed (5000 per hour), change log may not ' \ 'contain some issues. You can limit the number of issues fetched using the `--max-issues NUM` argument' def initialize - @options = Parser.parse_options fetch_github_token - github_options = {per_page: PER_PAGE_NUMBER} + github_options = { per_page: PER_PAGE_NUMBER } github_options[:oauth_token] = @github_token unless @github_token.nil? github_options[:endpoint] = options[:github_endpoint] unless options[:github_endpoint].nil? github_options[:site] = options[:github_endpoint] unless options[:github_site].nil? @@ -37,17 +35,17 @@ module GitHubChangelogGenerator @generator = Generator.new(@options) - @all_tags = self.get_all_tags - @issues, @pull_requests = self.fetch_issues_and_pull_requests + @all_tags = get_all_tags + @issues, @pull_requests = fetch_issues_and_pull_requests if @options[:pulls] - @pull_requests = self.get_filtered_pull_requests + @pull_requests = get_filtered_pull_requests else @pull_requests = [] end if @options[:issues] - @issues = self.get_filtered_issues + @issues = get_filtered_issues else @issues = [] end @@ -58,7 +56,6 @@ module GitHubChangelogGenerator end def detect_actual_closed_dates - if @options[:verbose] print "Fetching closed dates for issues...\r" end @@ -76,7 +73,7 @@ module GitHubChangelogGenerator find_closed_date_by_commit(pull_request) } } - threads.each { |thr| thr.join } + threads.each(&:join) if @options[:verbose] puts 'Fetching closed dates for issues: Done!' @@ -85,7 +82,7 @@ module GitHubChangelogGenerator 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 + # 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| @@ -105,7 +102,7 @@ module GitHubChangelogGenerator end } end - #TODO: assert issues, that remain without 'actual_date' hash for some reason. + # TODO: assert issues, that remain without 'actual_date' hash for some reason. end def print_json(json) @@ -118,7 +115,7 @@ module GitHubChangelogGenerator end pull_requests = [] begin - response = @github.pull_requests.list @options[:user], @options[:project], :state => 'closed' + response = @github.pull_requests.list @options[:user], @options[:project], state: 'closed' page_i = 0 response.each_page do |page| page_i += PER_PAGE_NUMBER @@ -134,7 +131,8 @@ module GitHubChangelogGenerator @pull_requests.each { |pr| fetched_pr = pull_requests.find { |fpr| - fpr.number == pr.number } + fpr.number == pr.number + } pr[:merged_at] = fetched_pr[:merged_at] pull_requests.delete(fetched_pr) } @@ -142,38 +140,34 @@ module GitHubChangelogGenerator if @options[:verbose] puts 'Fetching merged dates... Done!' end - end def get_filtered_pull_requests + fetch_merged_at_pull_requests - self.fetch_merged_at_pull_requests - - filtered_pull_requests = @pull_requests.select { |pr| pr[:merged_at] != nil } + filtered_pull_requests = @pull_requests.select { |pr| !pr[:merged_at].nil? } unless @options[:include_labels].nil? filtered_pull_requests = @pull_requests.select { |issue| - #add all labels from @options[:incluse_labels] array - (issue.labels.map { |label| label.name } & @options[:include_labels]).any? + # add all labels from @options[:incluse_labels] array + (issue.labels.map(&:name) & @options[:include_labels]).any? } end unless @options[:exclude_labels].nil? filtered_pull_requests = filtered_pull_requests.select { |issue| - #delete all labels from @options[:exclude_labels] array - !(issue.labels.map { |label| label.name } & @options[:exclude_labels]).any? + # delete all labels from @options[:exclude_labels] array + !(issue.labels.map(&:name) & @options[:exclude_labels]).any? } end if @options[:add_issues_wo_labels] - issues_wo_labels = @pull_requests.select { - # add issues without any labels - |issue| !issue.labels.map { |label| label.name }.any? + issues_wo_labels = @pull_requests.select { |issue| + !issue.labels.map(&:name).any? } filtered_pull_requests |= issues_wo_labels end - if @options[:verbose] puts "Filtered pull requests: #{filtered_pull_requests.count}" end @@ -182,16 +176,15 @@ module GitHubChangelogGenerator end def compund_changelog - log = "# Change Log\n\n" if @options[:unreleased_only] - log += self.generate_log_between_tags(self.all_tags[0], nil) + log += generate_log_between_tags(all_tags[0], nil) elsif @options[:tag1] and @options[:tag2] tag1 = @options[:tag1] tag2 = @options[:tag2] tags_strings = [] - self.all_tags.each { |x| tags_strings.push(x['name']) } + all_tags.each { |x| tags_strings.push(x['name']) } if tags_strings.include?(tag1) if tags_strings.include?(tag2) @@ -199,7 +192,7 @@ module GitHubChangelogGenerator hash = Hash[to_a] index1 = hash[tag1] index2 = hash[tag2] - log += self.generate_log_between_tags(self.all_tags[index1], self.all_tags[index2]) + log += generate_log_between_tags(all_tags[index1], all_tags[index2]) else puts "Can't find tag #{tag2} -> exit" exit @@ -209,7 +202,7 @@ module GitHubChangelogGenerator exit end else - log += self.generate_log_for_all_tags + log += generate_log_for_all_tags end log += "\n\n\\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*" @@ -218,38 +211,35 @@ module GitHubChangelogGenerator File.open(output_filename, 'w') { |file| file.write(log) } puts 'Done!' puts "Generated log placed in #{`pwd`.strip!}/#{output_filename}" - end def generate_log_for_all_tags - fetch_tags_dates if @options[:verbose] - puts "Sorting tags.." + puts 'Sorting tags..' end - @all_tags.sort_by! { |x| self.get_time_of_tag(x) }.reverse! + @all_tags.sort_by! { |x| get_time_of_tag(x) }.reverse! if @options[:verbose] - puts "Generating log.." + puts 'Generating log..' end - log = '' if @options[:unreleased] && @all_tags.count != 0 - unreleased_log = self.generate_log_between_tags(self.all_tags[0], nil) + unreleased_log = generate_log_between_tags(all_tags[0], nil) if unreleased_log log += unreleased_log end end - (1 ... self.all_tags.size).each { |index| - log += self.generate_log_between_tags(self.all_tags[index], self.all_tags[index-1]) + (1...all_tags.size).each { |index| + log += generate_log_between_tags(all_tags[index], all_tags[index - 1]) } if @all_tags.count != 0 - log += generate_log_between_tags(nil, self.all_tags.last) + log += generate_log_between_tags(nil, all_tags.last) end log @@ -267,18 +257,17 @@ module GitHubChangelogGenerator @all_tags.each { |tag| # explicit set @tag_times_hash to write data safety. threads << Thread.new { - self.get_time_of_tag(tag, @tag_times_hash) + get_time_of_tag(tag, @tag_times_hash) if @options[:verbose] - print "Fetching tags dates: #{i+1}/#{all}\r" - i+=1 + print "Fetching tags dates: #{i + 1}/#{all}\r" + i += 1 end - } } print " \r" - threads.each { |thr| thr.join } + threads.each(&:join) if @options[:verbose] puts "Fetching tags dates: #{i} Done!" @@ -292,7 +281,6 @@ module GitHubChangelogGenerator end def get_all_tags - if @options[:verbose] print "Fetching tags...\r" end @@ -328,12 +316,11 @@ module GitHubChangelogGenerator env_var = @options[:token] ? @options[:token] : (ENV.fetch 'CHANGELOG_GITHUB_TOKEN', nil) unless env_var - puts "Warning: No token provided (-t option) and variable $CHANGELOG_GITHUB_TOKEN was not found.".yellow - puts "This script can make only 50 requests to GitHub API per hour without token!".yellow + puts 'Warning: No token provided (-t option) and variable $CHANGELOG_GITHUB_TOKEN was not found.'.yellow + puts 'This script can make only 50 requests to GitHub API per hour without token!'.yellow end @github_token ||= env_var - end def generate_log_between_tags(older_tag, newer_tag) @@ -345,7 +332,7 @@ module GitHubChangelogGenerator older_tag_name = older_tag.nil? ? nil : older_tag['name'] if @options[:filter_issues_by_milestone] - #delete excess irrelevant issues (according milestones) + # 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 @@ -355,7 +342,7 @@ module GitHubChangelogGenerator return '' end - self.create_log(filtered_pull_requests, filtered_issues, newer_tag, older_tag_name) + create_log(filtered_pull_requests, filtered_issues, newer_tag, older_tag_name) end def filter_by_milestone(filtered_issues, newer_tag_name, src_array) @@ -364,18 +351,18 @@ module GitHubChangelogGenerator if issue.milestone.nil? true else - #check, that this milestone in tag list: + # 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) + # 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: + # check, that this milestone in tag list: milestone_is_tag = @all_tags.find { |tag| tag.name == issue.milestone.title } @@ -394,11 +381,10 @@ module GitHubChangelogGenerator end def delete_by_time(array, hash_key, older_tag = nil, newer_tag = nil) + fail 'At least one of the tags should be not nil!' if older_tag.nil? && newer_tag.nil? - raise 'At least one of the tags should be not nil!' if (older_tag.nil? && newer_tag.nil?) - - newer_tag_time = self.get_time_of_tag(newer_tag) - older_tag_time = self.get_time_of_tag(older_tag) + newer_tag_time = get_time_of_tag(newer_tag) + older_tag_time = get_time_of_tag(older_tag) array.select { |req| if req[hash_key] @@ -416,7 +402,6 @@ module GitHubChangelogGenerator tag_in_range_new = t <= newer_tag_time end - tag_in_range = (tag_in_range_old) && (tag_in_range_new) tag_in_range @@ -431,8 +416,7 @@ module GitHubChangelogGenerator # @param [String] older_tag_name # @return [String] def create_log(pull_requests, issues, newer_tag, older_tag_name = nil) - - newer_tag_time = newer_tag.nil? ? nil : self.get_time_of_tag(newer_tag) + newer_tag_time = newer_tag.nil? ? nil : get_time_of_tag(newer_tag) newer_tag_name = newer_tag.nil? ? nil : newer_tag['name'] github_site = options[:github_site] || 'https://github.com' @@ -454,7 +438,7 @@ module GitHubChangelogGenerator # Generate issues: issues_a = [] enhancement_a = [] - bugs_a =[] + bugs_a = [] issues.each { |dict| added = false @@ -504,8 +488,7 @@ module GitHubChangelogGenerator end def generate_header(log, newer_tag_name, newer_tag_name2, newer_tag_time, older_tag_name, project_url) - - #Generate date string: + # Generate date string: time_string = newer_tag_time.strftime @options[:format] # Generate tag name and link @@ -524,7 +507,6 @@ module GitHubChangelogGenerator end def get_time_of_tag(tag_name, tag_times_hash = @tag_times_hash) - if tag_name.nil? return nil end @@ -543,40 +525,36 @@ module GitHubChangelogGenerator end def get_filtered_issues - issues = @issues filtered_issues = issues unless @options[:include_labels].nil? filtered_issues = issues.select { |issue| - #add all labels from @options[:incluse_labels] array - (issue.labels.map { |label| label.name } & @options[:include_labels]).any? + # add all labels from @options[:incluse_labels] array + (issue.labels.map(&:name) & @options[:include_labels]).any? } end unless @options[:exclude_labels].nil? filtered_issues = filtered_issues.select { |issue| - #delete all labels from @options[:exclude_labels] array - !(issue.labels.map { |label| label.name } & @options[:exclude_labels]).any? + # delete all labels from @options[:exclude_labels] array + !(issue.labels.map(&:name) & @options[:exclude_labels]).any? } end if @options[:add_issues_wo_labels] - issues_wo_labels = issues.select { - # add issues without any labels - |issue| !issue.labels.map { |label| label.name }.any? + issues_wo_labels = issues.select { |issue| + !issue.labels.map(&:name).any? } filtered_issues |= issues_wo_labels end - if @options[:verbose] puts "Filtered issues: #{filtered_issues.count}" end filtered_issues - end def fetch_issues_and_pull_requests @@ -607,12 +585,12 @@ module GitHubChangelogGenerator # remove pull request from issues: issues_wo_pr = issues.select { |x| - x.pull_request == nil + x.pull_request.nil? } pull_requests = issues.select { |x| - x.pull_request != nil + !x.pull_request.nil? } - return issues_wo_pr, pull_requests + [issues_wo_pr, pull_requests] end def fetch_event_for_issues_and_pr @@ -623,8 +601,6 @@ module GitHubChangelogGenerator # Async fetching events: fetch_events_async(@issues + @pull_requests) - - end def fetch_events_async(issues) @@ -640,27 +616,24 @@ module GitHubChangelogGenerator puts GH_RATE_LIMIT_EXCEEDED_MSG.yellow end issue[:events] = obj.body - print "Fetching events for issues and PR: #{i+1}/#{@issues.count + @pull_requests.count}\r" - i +=1 + print "Fetching events for issues and PR: #{i + 1}/#{@issues.count + @pull_requests.count}\r" + i += 1 } } - threads.each { |thr| thr.join } + threads.each(&:join) threads = [] } - #to clear line from prev print + # to clear line from prev print print " \r" if @options[:verbose] puts "Fetching events for issues and PR: #{i} Done!" end - end - end - if __FILE__ == $0 + if __FILE__ == $PROGRAM_NAME GitHubChangelogGenerator::ChangelogGenerator.new.compund_changelog end - end diff --git a/lib/github_changelog_generator/generator.rb b/lib/github_changelog_generator/generator.rb index 06f265c..f1bf0e9 100644 --- a/lib/github_changelog_generator/generator.rb +++ b/lib/github_changelog_generator/generator.rb @@ -1,19 +1,18 @@ module GitHubChangelogGenerator class Generator - def initialize(options = nil) @options = options end def get_string_for_issue(issue) - encapsulated_title = self.encapsulate_string issue[:title] + encapsulated_title = encapsulate_string issue[:title] title_with_number = "#{encapsulated_title} [\\##{issue[:number]}](#{issue.html_url})" unless issue.pull_request.nil? if @options[:author] if issue.user.nil? - title_with_number += " ({Null user})" + title_with_number += ' ({Null user})' else title_with_number += " ([#{issue.user.login}](#{issue.user.html_url}))" end @@ -23,17 +22,14 @@ module GitHubChangelogGenerator end def encapsulate_string(string) - string.gsub! '\\', '\\\\' encpas_chars = %w(> * _ \( \) [ ] #) - encpas_chars.each { |char| + encpas_chars.each do |char| string.gsub! char, "\\#{char}" - } + end string end - end - -end \ No newline at end of file +end diff --git a/lib/github_changelog_generator/parser.rb b/lib/github_changelog_generator/parser.rb index 49320e1..ab8a127 100644 --- a/lib/github_changelog_generator/parser.rb +++ b/lib/github_changelog_generator/parser.rb @@ -6,32 +6,31 @@ require_relative 'version' module GitHubChangelogGenerator class Parser def self.parse_options - options = { - :tag1 => nil, - :tag2 => nil, - :format => '%Y-%m-%d', - :output => 'CHANGELOG.md', - :exclude_labels => %w(duplicate question invalid wontfix), - :pulls => true, - :issues => true, - :verbose => true, - :add_issues_wo_labels => true, - :add_pr_wo_labels => true, - :merge_prefix => '**Merged pull requests:**', - :issue_prefix => '**Closed issues:**', - :bug_prefix => '**Fixed bugs:**', - :enhancement_prefix => '**Implemented enhancements:**', - :author => true, - :filter_issues_by_milestone => true, - :max_issues => nil, - :compare_link => true, - :unreleased => true, - :unreleased_label => 'Unreleased', - :branch => 'origin' + tag1: nil, + tag2: nil, + format: '%Y-%m-%d', + output: 'CHANGELOG.md', + exclude_labels: %w(duplicate question invalid wontfix), + pulls: true, + issues: true, + verbose: true, + add_issues_wo_labels: true, + add_pr_wo_labels: true, + merge_prefix: '**Merged pull requests:**', + issue_prefix: '**Closed issues:**', + bug_prefix: '**Fixed bugs:**', + enhancement_prefix: '**Implemented enhancements:**', + author: true, + filter_issues_by_milestone: true, + max_issues: nil, + compare_link: true, + unreleased: true, + unreleased_label: 'Unreleased', + branch: 'origin' } - parser = OptionParser.new { |opts| + parser = OptionParser.new do |opts| opts.banner = 'Usage: github_changelog_generator [options]' opts.on('-u', '--user [USER]', 'Username of the owner of target GitHub repo') do |last| options[:user] = last @@ -99,7 +98,7 @@ module GitHubChangelogGenerator opts.on('--[no-]verbose', 'Run verbosely. Default is true') do |v| options[:verbose] = v end - opts.on('-v', '--version', 'Print version number') do |v| + opts.on('-v', '--version', 'Print version number') do |_v| puts "Version: #{GitHubChangelogGenerator::VERSION}" exit end @@ -107,7 +106,7 @@ module GitHubChangelogGenerator puts opts exit end - } + end parser.parse! @@ -126,10 +125,9 @@ module GitHubChangelogGenerator exit else options[:user] = match[1] - options[:project]= match[2] + options[:project] = match[2] end - end if !options[:user] && !options[:project] @@ -143,9 +141,9 @@ module GitHubChangelogGenerator puts "Detected user:#{match[1]}, project:#{match[2]}" options[:user], options[:project] = match[1], match[2] else - # try to find repo in format: - # origin https://github.com/skywinder/ChangelogMerger (fetch) - # https://github.com/skywinder/ChangelogMerger + # try to find repo in format: + # origin https://github.com/skywinder/ChangelogMerger (fetch) + # https://github.com/skywinder/ChangelogMerger match = /.*\/((?:-|\w|\.)*)\/((?:-|\w|\.)*).*/.match(remote) if match && match[1] && match[2] puts "Detected user:#{match[1]}, project:#{match[2]}" @@ -154,7 +152,6 @@ module GitHubChangelogGenerator end end - if !options[:user] || !options[:project] puts parser.banner exit diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b21a3f5..a46c911 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,23 @@ +# +# Author:: Enrico Stahn +# +# Copyright 2014, Zanui, +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'github_changelog_generator' + # This file was generated by the `rspec --init` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause @@ -40,9 +60,6 @@ RSpec.configure do |config| mocks.verify_partial_doubles = true end -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin # These two settings work together to allow you to limit a spec run # to individual examples or groups you care about by tagging them with # `:focus` metadata. When nothing is tagged with `:focus`, all examples @@ -87,5 +104,4 @@ RSpec.configure do |config| # test failures related to randomization by passing the same `--seed` value # as the one that triggered the failure. Kernel.srand config.seed -=end end From 9e69a1c8533430c3c42c61094f557ebdbef4cea0 Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Thu, 26 Mar 2015 15:53:46 +0200 Subject: [PATCH 5/8] add rubocop and rspec to Gemfile --- Gemfile | 9 ++++++++- Gemfile.lock | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 3601117..3f54b8d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,11 @@ source 'https://rubygems.org' + +gem 'rake' + gem 'github_api' gem 'colorize' -gem 'rake' + +group :test do + gem 'rspec' + gem 'rubocop' +end diff --git a/Gemfile.lock b/Gemfile.lock index 9e9a32c..457d0d2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,9 +2,13 @@ GEM remote: https://rubygems.org/ specs: addressable (2.3.6) + ast (2.0.0) + astrolabe (1.3.0) + parser (>= 2.2.0.pre.3, < 3.0) colorize (0.7.4) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) + diff-lcs (1.2.5) faraday (0.9.0) multipart-post (>= 1.2, < 3) github_api (0.12.2) @@ -29,8 +33,32 @@ GEM multi_json (~> 1.3) multi_xml (~> 0.5) rack (~> 1.2) + parser (2.2.0.3) + ast (>= 1.1, < 3.0) + powerpack (0.1.0) rack (1.5.2) + rainbow (2.0.0) rake (10.4.2) + rspec (3.2.0) + rspec-core (~> 3.2.0) + rspec-expectations (~> 3.2.0) + rspec-mocks (~> 3.2.0) + rspec-core (3.2.2) + rspec-support (~> 3.2.0) + rspec-expectations (3.2.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.2.0) + rspec-mocks (3.2.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.2.0) + rspec-support (3.2.2) + rubocop (0.29.1) + astrolabe (~> 1.3) + parser (>= 2.2.0.1, < 3.0) + powerpack (~> 0.1) + rainbow (>= 1.99.1, < 3.0) + ruby-progressbar (~> 1.4) + ruby-progressbar (1.7.5) thread_safe (0.3.4) PLATFORMS @@ -40,3 +68,5 @@ DEPENDENCIES colorize github_api rake + rspec + rubocop From 34cd8f75f775e2d732b8ac25a1574bd0db957240 Mon Sep 17 00:00:00 2001 From: Enrico Stahn Date: Thu, 26 Mar 2015 16:01:07 +1100 Subject: [PATCH 6/8] Configure travis to use bundler and new rake tasks --- .travis.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 51be3d1..e84ae12 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,13 @@ +--- +sudo: false +cache: bundler language: ruby -before_install: - - gem update --system - - gem --version + rvm: - 2.1.0 -gemfile: - - Gemfile + +script: + - bundle exec rake notifications: email: From 6ef182a1fc2d329bf9eacd3ca6add2eedc135908 Mon Sep 17 00:00:00 2001 From: Enrico Stahn Date: Thu, 26 Mar 2015 16:00:36 +1100 Subject: [PATCH 7/8] Add RSpec and Rubocop --- .rubocop.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..c441045 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,2 @@ +Metrics/LineLength: + Enabled: false From c5df1c22bbb785b8be5821cc692e3575c1aa8c50 Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Thu, 26 Mar 2015 16:27:49 +0200 Subject: [PATCH 8/8] add identations (rubocop fix) --- Gemfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 3f54b8d..2df9bd4 100644 --- a/Gemfile +++ b/Gemfile @@ -6,6 +6,6 @@ gem 'github_api' gem 'colorize' group :test do - gem 'rspec' - gem 'rubocop' + gem 'rspec' + gem 'rubocop' end