Merge branch 'release/1.5.0'

This commit is contained in:
Petr Korolev 2015-05-26 16:06:54 +03:00
commit a2b23e0f69
13 changed files with 408 additions and 217 deletions

View File

@ -6,3 +6,11 @@ Metrics/LineLength:
#http://viget.com/extend/just-use-double-quoted-ruby-strings
Style/StringLiterals:
EnforcedStyle: double_quotes
# Configuration parameters: CountComments.
Metrics/ClassLength:
Enabled: false
# Configuration parameters: CountComments.
Metrics/MethodLength:
Enabled: false

View File

@ -1,37 +1,27 @@
# This configuration was generated by `rubocop --auto-gen-config`
# on 2015-05-25 12:59:32 +0300 using RuboCop version 0.31.0.
# on 2015-05-26 16:00:55 +0300 using RuboCop version 0.31.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 16
# Offense count: 14
Metrics/AbcSize:
Max: 68
Max: 59
# Offense count: 4
# Configuration parameters: CountComments.
Metrics/ClassLength:
Enabled: false
# Offense count: 3
# Offense count: 1
Metrics/CyclomaticComplexity:
Max: 9
Max: 7
# Offense count: 22
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 117
# Offense count: 4
# Offense count: 1
Metrics/PerceivedComplexity:
Max: 12
Max: 8
# Offense count: 2
Style/AccessorMethodName:
Enabled: false
# Offense count: 6
# Offense count: 8
Style/Documentation:
Enabled: false

View File

@ -82,30 +82,35 @@ As output you will get `CHANGELOG.md` file with pretty *Markdown-formatted* chan
### Params
Type `github_changelog_generator --help` for detailed usage.
Usage: changelog_generator [options]
-u, --user [USER] Username of the owner of target GitHub repo
-p, --project [PROJECT] Name of project on GitHub
-t, --token [TOKEN] To make more than 50 requests per hour your GitHub token required. You can generate it here: https://github.com/settings/tokens/new
-f, --date-format [FORMAT] Date format. Default is %d/%m/%y
-o, --output [NAME] Output file. Default is CHANGELOG.md
--[no-]verbose Run verbosely. Default is true
--[no-]issues Include closed issues to changelog. Default is true
--[no-]issues-wo-labels Include closed issues without labels to changelog. Default is true
--[no-]pr-wo-labels Include pull requests without labels to changelog. Default is true
--[no-]pull-requests Include pull-requests to changelog. Default is true
--[no-]filter-by-milestone Use milestone to detect when issue was resolved. Default is true
--[no-]author Add author of pull-request in the end. Default is true
--unreleased-only Generate log from unreleased closed issues only.
--[no-]unreleased Add to log unreleased closed issues. Default is true
--[no-]compare-link Include compare link between older version and newer version. Default is true
--include-labels x,y,z Issues only with that labels will be included to changelog. Default is 'bug,enhancement'
--exclude-labels x,y,z Issues with that labels will be always excluded from changelog. Default is 'duplicate,question,invalid,wontfix'
--max-issues [NUMBER] Max number of issues to fetch from GitHub. Default is unlimited.
--github-site [URL] The Enterprise Github site on which your project is hosted.
--github-api [URL] The enterprise endpoint to use for your Github API.
--future-release [RELEASE-VERSION] Put the unreleased changes in the specified release number.
-v, --version Print version number
-h, --help Displays Help
Usage: github_changelog_generator [options]
-u, --user [USER] Username of the owner of target GitHub repo
-p, --project [PROJECT] Name of project on GitHub
-t, --token [TOKEN] To make more than 50 requests per hour your GitHub token is required. You can generate it at: https://github.com/settings/tokens/new
-f, --date-format [FORMAT] Date format. Default is %Y-%m-%d
-o, --output [NAME] Output file. Default is CHANGELOG.md
--[no-]issues Include closed issues in changelog. Default is true
--[no-]issues-wo-labels Include closed issues without labels in changelog. Default is true
--[no-]pr-wo-labels Include pull requests without labels in changelog. Default is true
--[no-]pull-requests Include pull-requests in changelog. Default is true
--[no-]filter-by-milestone Use milestone to detect when issue was resolved. Default is true
--[no-]author Add author of pull-request in the end. Default is true
--unreleased-only Generate log from unreleased closed issues only.
--[no-]unreleased Add to log unreleased closed issues. Default is true
--unreleased-label [label] Add to log unreleased closed issues. Default is true
--[no-]compare-link Include compare link (Full Changelog) between older version and newer version. Default is true
--include-labels x,y,z Only issues with the specified labels will be included in the changelog. Default is 'bug,enhancement'
--exclude-labels x,y,z Issues with the specified labels will be always excluded from changelog. Default is 'duplicate,question,invalid,wontfix'
--between-tags x,y,z Change log will be filled only between specified tags
--exclude-tags x,y,z Change log will be exclude specified tags
--max-issues [NUMBER] Max number of issues to fetch from GitHub. Default is unlimited
--github-site [URL] The Enterprise Github site on which your project is hosted.
--github-api [URL] The enterprise endpoint to use for your Github API.
--simple-list Create simple list from issues and pull requests. Default is false.
--future-release [RELEASE-VERSION]
Put the unreleased changes in the specified release number.
--[no-]verbose Run verbosely. Default is true
-v, --version Print version number
-h, --help Displays Help
### GitHub token

View File

@ -15,7 +15,7 @@ module GitHubChangelogGenerator
"This script can make only 50 requests to GitHub API per hour without token!"
def initialize(options = {})
@options = options
@options = options || {}
@logger = Logger.new(STDOUT)
@logger.formatter = proc do |_severity, _datetime, _progname, msg|
@ -28,8 +28,8 @@ module GitHubChangelogGenerator
@tag_times_hash = {}
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?
github_options[:endpoint] = @options[:github_endpoint] unless @options[:github_endpoint].nil?
github_options[:site] = @options[:github_endpoint] unless @options[:github_site].nil?
@github = check_github_response { Github.new github_options }
end

View File

@ -2,6 +2,7 @@ require "github_changelog_generator/fetcher"
require_relative "generator_generation"
require_relative "generator_fetcher"
require_relative "generator_processor"
require_relative "generator_tags"
module GitHubChangelogGenerator
# Default error for ChangelogGenerator
@ -17,13 +18,9 @@ module GitHubChangelogGenerator
# generator = GitHubChangelogGenerator::Generator.new
# content = generator.compound_changelog
def initialize(options = nil)
@options = options
@options = options || {}
@fetcher = GitHubChangelogGenerator::Fetcher.new @options
fetch_tags
fetch_issues_and_pr
end
def fetch_issues_and_pr
@ -37,20 +34,6 @@ module GitHubChangelogGenerator
detect_actual_closed_dates(@issues + @pull_requests)
end
def fetch_tags
# @all_tags = get_filtered_tags
@all_tags = @fetcher.get_all_tags
fetch_tags_dates
sort_tags_by_date
end
# Sort all tags by date
def sort_tags_by_date
puts "Sorting tags..." if @options[:verbose]
@all_tags.sort_by! { |x| @fetcher.get_time_of_tag(x) }.reverse!
end
# Encapsulate characters to make markdown look as expected.
#
# @param [String] string
@ -74,14 +57,7 @@ module GitHubChangelogGenerator
# @param [String] older_tag_name Older tag, used for the links. Could be nil for last tag.
# @return [String] Ready and parsed section
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)
if newer_tag.nil? && @options[:future_release]
newer_tag_name = @options[:future_release]
newer_tag_link = @options[:future_release]
else
newer_tag_name = newer_tag.nil? ? @options[:unreleased_label] : newer_tag["name"]
newer_tag_link = newer_tag.nil? ? "HEAD" : newer_tag_name
end
newer_tag_link, newer_tag_name, newer_tag_time = detect_link_tag_time(newer_tag)
github_site = options[:github_site] || "https://github.com"
project_url = "#{github_site}/#{@options[:user]}/#{@options[:project]}"
@ -90,11 +66,7 @@ module GitHubChangelogGenerator
if @options[:issues]
# Generate issues:
bugs_a, enhancement_a, issues_a = parse_by_sections(issues)
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])
log += issues_to_log(issues)
end
if @options[:pulls]
@ -105,6 +77,20 @@ module GitHubChangelogGenerator
log
end
# Generate ready-to-paste log from list of issues.
#
# @param [Array] issues
# @return [String] generated log for issues
def issues_to_log(issues)
log = ""
bugs_a, enhancement_a, issues_a = parse_by_sections(issues)
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])
log
end
# This method sort issues by types
# (bugs, features, or just closed issues) by labels
#

View File

@ -14,25 +14,19 @@ module GitHubChangelogGenerator
# Async fetching of all tags dates
def fetch_tags_dates
print "Fetching tag dates...\r" if @options[:verbose]
# Async fetching tags:
threads = []
i = 0
all = @all_tags.count
@all_tags.each do |tag|
print " \r"
threads << Thread.new do
@fetcher.get_time_of_tag(tag)
if @options[:verbose]
print "Fetching tags dates: #{i + 1}/#{all}\r"
i += 1
end
print "Fetching tags dates: #{i + 1}/#{all}\r" if @options[:verbose]
i += 1
end
end
print " \r"
threads.each(&:join)
puts "Fetching tags dates: #{i}" if @options[:verbose]
end

View File

@ -4,36 +4,42 @@ module GitHubChangelogGenerator
#
# @return [String] Generated change log file
def compound_changelog
fetch_and_filter_tags
fetch_issues_and_pr
log = "# Change Log\n\n"
if @options[:unreleased_only]
log += generate_log_between_tags(all_tags[0], nil)
elsif @options[:tag1] && @options[:tag2]
tag1 = @options[:tag1]
tag2 = @options[:tag2]
tags_strings = []
all_tags.each { |x| tags_strings.push(x["name"]) }
if tags_strings.include?(tag1)
if tags_strings.include?(tag2)
to_a = tags_strings.map.with_index.to_a
hash = Hash[to_a]
index1 = hash[tag1]
index2 = hash[tag2]
log += generate_log_between_tags(all_tags[index1], all_tags[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 += 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)*"
@log = log
@log = log
end
# @return [String] temp method should be removed soon
def generate_for_2_tags(log)
tag1 = @options[:tag1]
tag2 = @options[:tag2]
tags_strings = []
all_tags.each { |x| tags_strings.push(x["name"]) }
if tags_strings.include?(tag1)
if tags_strings.include?(tag2)
to_a = tags_strings.map.with_index.to_a
hash = Hash[to_a]
index1 = hash[tag1]
index2 = hash[tag2]
log += generate_log_between_tags(all_tags[index1], all_tags[index2])
else
fail ChangelogGeneratorError, "Can't find tag #{tag2} -> exit".red
end
else
fail ChangelogGeneratorError, "Can't find tag #{tag1} -> exit".red
end
log
end
# @param [Array] issues List of issues on sub-section
@ -86,18 +92,10 @@ module GitHubChangelogGenerator
# @param [String] older_tag all issues before this tag date will be excluded. May be nil, if it's first tag
# @param [String] newer_tag all issue after this tag will be excluded. May be nil for unreleased section
def generate_log_between_tags(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)
filtered_issues, filtered_pull_requests = filter_issues_for_tags(newer_tag, older_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). Issue #22.
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 newer_tag.nil? && filtered_issues.empty? && filtered_pull_requests.empty?
# do not generate empty unreleased section
return ""
@ -106,6 +104,23 @@ module GitHubChangelogGenerator
create_log(filtered_pull_requests, filtered_issues, newer_tag, older_tag_name)
end
# Apply all filters to issues and pull requests
#
# @return [Array] filtered issues and pull requests
def filter_issues_for_tags(newer_tag, older_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"]
if @options[:filter_issues_by_milestone]
# delete excess irrelevant issues (according milestones). Issue #22.
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
[filtered_issues, filtered_pull_requests]
end
# The full cycle of generation for whole project
# @return [String] The complete change log
def generate_log_for_all_tags
@ -125,7 +140,7 @@ module GitHubChangelogGenerator
def generate_unreleased_section
log = ""
if @options[:unreleased] && @all_tags.count != 0
if @options[:unreleased]
unreleased_log = generate_log_between_tags(all_tags[0], nil)
log += unreleased_log if unreleased_log
end

View File

@ -13,7 +13,44 @@ module GitHubChangelogGenerator
issues
end
def filter_by_milestone(filtered_issues, newer_tag_name, src_array)
# @return [Array] filtered issues accourding milestone
def filter_by_milestone(filtered_issues, tag_name, all_issues)
remove_issues_in_milestones(filtered_issues)
unless tag_name.nil?
# add missed issues (according milestones)
issues_to_add = find_issues_to_add(all_issues, tag_name)
filtered_issues |= issues_to_add
end
filtered_issues
end
# Add all issues, that should be in that tag, according milestone
#
# @param [Array] all_issues
# @param [String] tag_name
# @return [Array] issues with milestone #tag_name
def find_issues_to_add(all_issues, tag_name)
all_issues.select do |issue|
if issue.milestone.nil?
false
else
# check, that this milestone in tag list:
milestone_is_tag = @all_tags.find do |tag|
tag.name == issue.milestone.title
end
if milestone_is_tag.nil?
false
else
issue.milestone.title == tag_name
end
end
end
end
# @return [Array] array with removed issues, that contain milestones with same name as a tag
def remove_issues_in_milestones(filtered_issues)
filtered_issues.select! do |issue|
# leave issues without milestones
if issue.milestone.nil?
@ -23,29 +60,6 @@ module GitHubChangelogGenerator
@all_tags.find { |tag| tag.name == issue.milestone.title }.nil?
end
end
unless newer_tag_name.nil?
# add missed issues (according milestones)
issues_to_add = src_array.select do |issue|
if issue.milestone.nil?
false
else
# check, that this milestone in tag list:
milestone_is_tag = @all_tags.find do |tag|
tag.name == issue.milestone.title
end
if milestone_is_tag.nil?
false
else
issue.milestone.title == newer_tag_name
end
end
end
filtered_issues |= issues_to_add
end
filtered_issues
end
# Method filter issues, that belong only specified tag range
@ -55,26 +69,19 @@ module GitHubChangelogGenerator
# @param [String] newer_tag all issue after this tag will be excluded. May be nil for unreleased section
# @return [Array] filtered issues
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?
# in case if not tags specified - return unchanged array
return array 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 do |req|
if req[hash_key]
t = Time.parse(req[hash_key]).utc
time = 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
tag_in_range_old = tag_newer_old_tag?(older_tag_time, time)
if newer_tag_time.nil?
tag_in_range_new = true
else
tag_in_range_new = t <= newer_tag_time
end
tag_in_range_new = tag_older_new_tag?(newer_tag_time, time)
tag_in_range = (tag_in_range_old) && (tag_in_range_new)
@ -85,39 +92,50 @@ module GitHubChangelogGenerator
end
end
def tag_older_new_tag?(newer_tag_time, time)
if newer_tag_time.nil?
tag_in_range_new = true
else
tag_in_range_new = time <= newer_tag_time
end
tag_in_range_new
end
def tag_newer_old_tag?(older_tag_time, t)
if older_tag_time.nil?
tag_in_range_old = true
else
tag_in_range_old = t > older_tag_time
end
tag_in_range_old
end
# Include issues with labels, specified in :include_labels
# @param [Array] issues to filter
# @return [Array] filtered array of issues
def include_issues_by_labels(issues)
filtered_issues = @options[:include_labels].nil? ? issues : issues.select do |issue|
labels = issue.labels.map(&:name) & @options[:include_labels]
(labels).any?
end
filtered_issues = filter_by_include_labels(issues)
filtered_issues |= filter_wo_labels(issues)
filtered_issues
end
# @return [Array] issues without labels or empty array if add_issues_wo_labels is false
def filter_wo_labels(issues)
if @options[:add_issues_wo_labels]
issues_wo_labels = issues.select do |issue|
!issue.labels.map(&:name).any?
end
filtered_issues |= issues_wo_labels
return issues_wo_labels
end
filtered_issues
[]
end
# Return tags after filtering tags in lists provided by option: --between-tags & --exclude-tags
#
# @return [Array]
def get_filtered_tags
all_tags = @fetcher.get_all_tags
filtered_tags = []
if @options[:between_tags]
@options[:between_tags].each do |tag|
unless all_tags.include? tag
puts "Warning: can't find tag #{tag}, specified with --between-tags option.".yellow
end
end
filtered_tags = all_tags.select { |tag| @options[:between_tags].include? tag }
def filter_by_include_labels(issues)
filtered_issues = @options[:include_labels].nil? ? issues : issues.select do |issue|
labels = issue.labels.map(&:name) & @options[:include_labels]
(labels).any?
end
filtered_tags
filtered_issues
end
# General filtered function

View File

@ -0,0 +1,70 @@
module GitHubChangelogGenerator
class Generator
# fetch, filter tags, fetch dates and sort them in time order
def fetch_and_filter_tags
@all_tags = get_filtered_tags(@fetcher.get_all_tags)
fetch_tags_dates
sort_tags_by_date
end
# Sort all tags by date
def sort_tags_by_date
puts "Sorting tags..." if @options[:verbose]
@all_tags.sort_by! { |x| @fetcher.get_time_of_tag(x) }.reverse!
end
# Detect link, name and time for specified tag.
#
# @param [Hash] newer_tag newer tag. Can be nil, if it's Unreleased section.
# @return [Array] link, name and time of the tag
def detect_link_tag_time(newer_tag)
# if tag is nil - set current time
newer_tag_time = newer_tag.nil? ? Time.new : @fetcher.get_time_of_tag(newer_tag)
# if it's future release tag - set this value
if newer_tag.nil? && @options[:future_release]
newer_tag_name = @options[:future_release]
newer_tag_link = @options[:future_release]
else
# put unreleased label if there is no name for the tag
newer_tag_name = newer_tag.nil? ? @options[:unreleased_label] : newer_tag["name"]
newer_tag_link = newer_tag.nil? ? "HEAD" : newer_tag_name
end
[newer_tag_link, newer_tag_name, newer_tag_time]
end
# Return tags after filtering tags in lists provided by option: --between-tags & --exclude-tags
#
# @return [Array]
def get_filtered_tags(all_tags)
filtered_tags = filter_between_tags(all_tags)
filter_excluded_tags(filtered_tags)
end
def filter_between_tags(all_tags)
filtered_tags = all_tags
if @options[:between_tags]
@options[:between_tags].each do |tag|
unless all_tags.include? tag
puts "Warning: can't find tag #{tag}, specified with --between-tags option.".yellow
end
end
filtered_tags = all_tags.select { |tag| @options[:between_tags].include? tag }
end
filtered_tags
end
def filter_excluded_tags(all_tags)
filtered_tags = all_tags
if @options[:exclude_tags]
@options[:exclude_tags].each do |tag|
unless all_tags.include? tag
puts "Warning: can't find tag #{tag}, specified with --between-tags option.".yellow
end
end
filtered_tags = all_tags.reject { |tag| @options[:exclude_tags].include? tag }
end
filtered_tags
end
end
end

View File

@ -5,34 +5,32 @@ require_relative "version"
module GitHubChangelogGenerator
class Parser
# parse options with optparse
def self.parse_options
options = {
tag1: nil,
tag2: nil,
date_format: "%Y-%m-%d",
output: "CHANGELOG.md",
issues: true,
add_issues_wo_labels: true,
add_pr_wo_labels: true,
pulls: true,
filter_issues_by_milestone: true,
author: true,
unreleased: true,
unreleased_label: "Unreleased",
compare_link: true,
include_labels: %w(bug enhancement),
exclude_labels: %w(duplicate question invalid wontfix),
max_issues: nil,
simple_list: false,
verbose: true,
options = get_default_options
merge_prefix: "**Merged pull requests:**",
issue_prefix: "**Closed issues:**",
bug_prefix: "**Fixed bugs:**",
enhancement_prefix: "**Implemented enhancements:**",
git_remote: "origin"
}
parser = setup_parser(options)
parser.parse!
detect_user_and_project(options)
if !options[:user] || !options[:project]
puts parser.banner
exit
end
if options[:verbose]
puts "Performing task with options:"
pp options
puts ""
end
options
end
# setup parsing options
def self.setup_parser(options)
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|
@ -86,6 +84,12 @@ module GitHubChangelogGenerator
opts.on("--exclude-labels x,y,z", Array, 'Issues with the specified labels will be always excluded from changelog. Default is \'duplicate,question,invalid,wontfix\'') do |list|
options[:exclude_labels] = list
end
opts.on("--between-tags x,y,z", Array, "Change log will be filled only between specified tags") do |list|
options[:between_tags] = list
end
opts.on("--exclude-tags x,y,z", Array, "Change log will be exclude specified tags") do |list|
options[:exclude_tags] = list
end
opts.on("--max-issues [NUMBER]", Integer, "Max number of issues to fetch from GitHub. Default is unlimited") do |max|
options[:max_issues] = max
end
@ -113,25 +117,41 @@ module GitHubChangelogGenerator
exit
end
end
parser
end
parser.parse!
detect_user_and_project(options)
if !options[:user] || !options[:project]
puts parser.banner
exit
end
if options[:verbose]
puts "Performing task with options:"
pp options
puts ""
end
# just get default options
def self.get_default_options
options = {
tag1: nil,
tag2: nil,
date_format: "%Y-%m-%d",
output: "CHANGELOG.md",
issues: true,
add_issues_wo_labels: true,
add_pr_wo_labels: true,
pulls: true,
filter_issues_by_milestone: true,
author: true,
unreleased: true,
unreleased_label: "Unreleased",
compare_link: true,
include_labels: %w(bug enhancement),
exclude_labels: %w(duplicate question invalid wontfix),
max_issues: nil,
simple_list: false,
verbose: true,
merge_prefix: "**Merged pull requests:**",
issue_prefix: "**Closed issues:**",
bug_prefix: "**Fixed bugs:**",
enhancement_prefix: "**Implemented enhancements:**",
git_remote: "origin"
}
options
end
# Detects user and project from git
def self.detect_user_and_project(options)
options[:user], options[:project] = user_project_from_option(ARGV[0], ARGV[1], options[:github_site])
if !options[:user] || !options[:project]
@ -149,12 +169,13 @@ module GitHubChangelogGenerator
#
# @param [String] output of git remote command
# @return [Array] user and project
def self.user_project_from_option(arg0, arg2, github_site = "github.com")
def self.user_project_from_option(arg0, arg1, github_site = nil)
user = nil
project = nil
if arg0 && !arg2
github_site ||= "github.com"
if arg0 && !arg1
# this match should parse strings such "https://github.com/skywinder/Github-Changelog-Generator" or "skywinder/Github-Changelog-Generator" to user and name
puts arg0
match = /(?:.+#{Regexp.escape(github_site)}\/)?(.+)\/(.+)/.match(arg0)
begin

View File

@ -1,3 +1,3 @@
module GitHubChangelogGenerator
VERSION = "1.4.1"
VERSION = "1.5.0"
end

View File

@ -0,0 +1,69 @@
describe GitHubChangelogGenerator::Generator do
describe "#filter_between_tags" do
context "when between_tags nil" do
before do
@generator = GitHubChangelogGenerator::Generator.new(between_tags: nil)
end
subject do
@generator.get_filtered_tags(%w(1 2 3))
end
it { is_expected.to be_a(Array) }
it { is_expected.to match_array(%w(1 2 3)) }
end
context "when between_tags same as input array" do
before do
@generator = GitHubChangelogGenerator::Generator.new(between_tags: %w(1 2 3))
end
subject do
@generator.get_filtered_tags(%w(1 2 3))
end
it { is_expected.to be_a(Array) }
it { is_expected.to match_array(%w(1 2 3)) }
end
context "when between_tags filled with correct values" do
before do
@generator = GitHubChangelogGenerator::Generator.new(between_tags: %w(1 2))
end
subject do
@generator.get_filtered_tags(%w(1 2 3))
end
it { is_expected.to be_a(Array) }
it { is_expected.to match_array(%w(1 2)) }
end
context "when between_tags filled with invalid values" do
before do
@generator = GitHubChangelogGenerator::Generator.new(between_tags: %w(1 q w))
end
subject do
@generator.get_filtered_tags(%w(1 2 3))
end
it { is_expected.to be_a(Array) }
it { is_expected.to match_array(%w(1)) }
end
end
describe "#get_filtered_tags" do
subject { generator.get_filtered_tags(%w(1 2 3 4 5)) }
# before { generator.get_filtered_tags(%w(1 2 3 4 5)) }
context "with excluded and between tags" do
let(:generator) { GitHubChangelogGenerator::Generator.new(between_tags: %w(1 2 3), exclude_tags: %w(2)) }
it { is_expected.to be_a Array }
it { is_expected.to match_array(%w(1 3)) }
end
end
describe "#filter_excluded_tags" do
subject { generator.filter_excluded_tags(%w(1 2 3)) }
context "with valid excluded tags" do
let(:generator) { GitHubChangelogGenerator::Generator.new(exclude_tags: %w(3)) }
it { is_expected.to be_a Array }
it { is_expected.to match_array(%w(1 2)) }
end
end
end

View File

@ -1,5 +1,5 @@
describe GitHubChangelogGenerator::Parser do
describe "#self.user_project_from_remote" do
describe ".user_project_from_remote" do
context "when remote is 1" do
subject { GitHubChangelogGenerator::Parser.user_project_from_remote("origin https://github.com/skywinder/ActionSheetPicker-3.0 (fetch)") }
it { is_expected.to be_a(Array) }
@ -26,7 +26,7 @@ describe GitHubChangelogGenerator::Parser do
it { is_expected.to match_array([nil, nil]) }
end
end
describe "#self.user_project_from_option" do
describe ".user_project_from_option" do
# context "when option is invalid" do
# it("should exit") { expect { GitHubChangelogGenerator::Parser.user_project_from_option("blah", nil) }.to raise_error(SystemExit) }
# end
@ -41,5 +41,20 @@ describe GitHubChangelogGenerator::Parser do
it { is_expected.to be_a(Array) }
it { is_expected.to match_array([nil, nil]) }
end
context "when site is nil" do
subject { GitHubChangelogGenerator::Parser.user_project_from_option("skywinder/ActionSheetPicker-3.0", nil, nil) }
it { is_expected.to be_a(Array) }
it { is_expected.to match_array(["skywinder", "ActionSheetPicker-3.0"]) }
end
context "when site is valid" do
subject { GitHubChangelogGenerator::Parser.user_project_from_option("skywinder/ActionSheetPicker-3.0", nil, "https://codeclimate.com") }
it { is_expected.to be_a(Array) }
it { is_expected.to match_array(["skywinder", "ActionSheetPicker-3.0"]) }
end
context "when second arg is not nil" do
subject { GitHubChangelogGenerator::Parser.user_project_from_option("skywinder/ActionSheetPicker-3.0", "blah", nil) }
it { is_expected.to be_a(Array) }
it { is_expected.to match_array([nil, nil]) }
end
end
end