lib/capistrano/committed.rb
require 'capistrano/committed/version'
require 'capistrano/committed/i18n'
require 'capistrano/committed/github_api'
require 'capistrano/committed/output'
module Capistrano
module Committed
class << self
@@settings = {}
def import_settings(settings, merge = nil)
merge.nil? ? @@settings = settings : @@settings.merge!(settings)
end
def get_setting(setting, variable = nil)
variable.nil? ? @@settings[setting] : variable
end
def revision_search_regex(revision_line = nil)
revision_line = get_setting(:revision_line, revision_line)
check_type __callee__, 'revision_line', revision_line.is_a?(String)
search = Regexp.escape(revision_line)
search = search.gsub('%\{', '(?<').gsub('\}', '>.+)')
Regexp.new(search)
end
def get_revisions_from_lines(lines, search = nil, branch = nil, limit = nil)
check_type __callee__, 'lines', lines.is_a?(Array)
lines.each_with_index do |line, index|
check_type __callee__, format('lines[%<index>d]', index: index), line.is_a?(String)
end
search = revision_search_regex if search.nil?
check_type __callee__, 'search', search.is_a?(Regexp)
branch = get_setting(:branch, branch)
check_type __callee__, 'branch', (branch.is_a?(Symbol) || branch.is_a?(String))
limit = get_setting(:revision_limit, limit)
check_type __callee__, 'limit', limit.is_a?(Integer)
revisions = {}
lines.each do |line|
matches = search.match(line)
next if matches.nil?
next unless matches[:branch].to_s == branch.to_s
revisions[matches[:release]] = {
branch: matches[:branch],
sha: matches[:sha],
release: matches[:release],
user: matches[:user],
entries: {}
}
# Only store a certain number of revisions
break if revisions.count == limit
end
pad_revisions(revisions)
end
def add_dates_to_revisions(revisions, github, git_user = nil, git_repo = nil)
check_type __callee__, 'revisions', revisions.is_a?(Hash)
check_type __callee__, 'github', github.is_a?(Capistrano::Committed::GithubApi)
git_user = check_git_user(git_user)
git_repo = check_git_repo(git_repo)
revisions.each do |release, revision|
next if %i[next previous].include? release
commit = github.get_commit(git_user, git_repo, revision[:sha])
revisions[release][:date] = commit[:commit][:committer][:date] unless commit.nil?
end
end
def get_earliest_date_from_revisions(revisions)
check_type __callee__, 'revisions', revisions.is_a?(Hash)
revisions.values.map { |r| Time.parse(r[:date]) unless r[:date].nil? }.compact.min
end
def days_to_seconds(days)
check_type __callee__, 'days', days.is_a?(Numeric)
days * 24 * 60 * 60
end
def add_buffer_to_time(time, buffer_in_days = nil)
check_type __callee__, 'time', time.is_a?(Time)
buffer_in_days = get_setting(:commit_buffer, buffer_in_days)
check_type __callee__, 'buffer_in_days', buffer_in_days.is_a?(Numeric)
(time - days_to_seconds(buffer_in_days)).iso8601
end
def get_issue_urls(message, issue_match = nil, issue_postprocess = nil, issue_url = nil)
check_type __callee__, 'message', message.is_a?(String)
issue_match = check_issue_match(issue_match)
issue_postprocess = check_issue_postprocess(issue_postprocess)
issue_url = check_issue_url(issue_url)
return [] unless (matches = message.scan(Regexp.new(issue_match)))
matches.map! do |match|
postprocess_issue_url(issue_postprocess, issue_url, match[0])
end.uniq
end
private
def check_type(method, param, condition)
raise TypeError, t('committed.error.helpers.valid_param', method: method, param: param) unless condition
end
def check_git_user(git_user)
git_user = get_setting(:user, git_user)
check_type __callee__, 'git_user', git_user.is_a?(String)
git_user
end
def check_git_repo(git_repo)
git_repo = get_setting(:repo, git_repo)
check_type __callee__, 'git_repo', git_repo.is_a?(String)
git_repo
end
def check_issue_match(issue_match)
issue_match = get_setting(:issue_match, issue_match)
check_type __callee__, 'issue_match', (issue_match.is_a?(String) || issue_match.is_a?(Regexp))
issue_match
end
def check_issue_postprocess(issue_postprocess)
issue_postprocess = get_setting(:issue_postprocess, issue_postprocess)
check_type __callee__, 'issue_postprocess', issue_postprocess.is_a?(Array)
issue_postprocess.each do |method|
check_type __callee__, format('issue_postprocess[:%<method>s]', method: method.to_s), method.is_a?(Symbol)
end
issue_postprocess
end
def check_issue_url(issue_url)
issue_url = get_setting(:issue_url, issue_url)
check_type __callee__, 'issue_url', issue_url.is_a?(String)
issue_url
end
def postprocess_issue_url(issue_postprocess, issue_url, issue)
issue_postprocess.each { |method| issue = issue.send(method) }
format(issue_url, issue)
end
def pad_revisions(revisions)
check_type __callee__, 'revisions', revisions.is_a?(Hash)
unless revisions.empty?
# Sort revisions by release date
revisions = Hash[revisions.sort { |a, b| b[1][:release] <=> a[1][:release] }]
# Add the "previous" revision
revisions[:previous] = { release: :previous, entries: {} }
# Add the "next" revision
revisions = { next: { release: :next, entries: {} } }.merge(revisions)
end
revisions
end
end
end
end
load File.expand_path('tasks/committed.rake', __dir__)