class CaretakerCore
Docs to go here
Description should go here
This is the core file @author Wolf
Description should go here
Description should go here
Description should go here
Description should go here
Constants
- CATEGORIES
- DEFAULT_CATEGORY
- DEFAULT_CONFIG
- INITIAL_TAG
Class Constants
- VERSION
Public Class Methods
Docs to go here
# File lib/caretaker-core.rb, line 20 def run(options = {}) # Will throw an exception if not a git repo check_for_git_repo # Set the initial config and handle user supplied options config = init_config(options) # Get URL and slug for the repo, will throw and exception if no remote origin is set repository, slug = git_repo_details # Add to config for easy access config[:repo_url] = repository # Really do the processing tags, chronological, categorised = real_process(config) # Return the data to the calling function { :tags => tags, :commits => { :chronological => chronological, :categorised => categorised }, :repo => { :url => repository, :slug => slug } }.to_json end
Private Class Methods
Are we running this from within a git repo??
# File lib/caretaker-core/git.rb, line 14 def check_for_git_repo raise StandardError.new('Directory does not contain a git repository - aborting') unless execute_command('git rev-parse --show-toplevel') end
Execute a given command and return the output from stdout or false if it fails
# File lib/caretaker-core/git.rb, line 65 def execute_command(cmd) Open3.popen3(cmd) do |_stdin, stdout, _stderr, wait_thr| return stdout.read.chomp if wait_thr.value.success? end false end
# File lib/caretaker-core/utils.rb, line 23 def extract_tag(refs, old_tag) tag = old_tag if refs.include? 'tag: ' refs = refs.gsub(/.*tag:/i, '') refs = refs.gsub(/,.*/i, '') tag = refs.gsub(/\).*/i, '') end tag.to_s.strip end
# File lib/caretaker-core/core.rb, line 111 def generate_pr_link(matches) pr_number = get_pr_number(matches) message = "Merge pull request ##{pr_number}" [message, pr_number] end
Make everything else private so it cannot be accessed directly
# File lib/caretaker-core/tags.rb, line 15 def generate_tag_list(parsed) parsed.keys end
This method reeks of :reek:DuplicateMethodCall, :reek:NestedIterators rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
# File lib/caretaker-core/core.rb, line 91 def get_category(commit_message) commit_message_downcase = commit_message.downcase # Does it match a primary category ? category = CATEGORIES.select { |key, _values| commit_message_downcase.start_with?(key.downcase) }.map(&:first).join # If not a primary category, does it match one of the aliases? category = CATEGORIES.select { |_key, values| values.any? { |value| commit_message_downcase.start_with?(value.downcase) } }.map(&:first).join if category.empty? # If in doubt set to the default category = DEFAULT_CATEGORY if category.empty? category end
comment to go here
# File lib/caretaker-core/git.rb, line 43 def get_child_messages(parent) body = execute_command("git log --pretty=format:'%b' -n 1 #{parent}") body.split("\n").each { |line| line.sub!('*', '') }.map(&:strip).reject(&:empty?).map { |line| line } unless body.empty? end
# File lib/caretaker-core/core.rb, line 69 def get_parts(line, tag) date, hash, hash_full, commit_message, tag = split_log_entries(line, tag) commit_message, child_commit_messages, commit_type = process_commit_message(commit_message, hash) category = get_category(commit_message) [hash, hash_full, commit_message, child_commit_messages, commit_type, category, date, tag] end
rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
# File lib/caretaker-core/core.rb, line 107 def get_pr_number(all_matches) all_matches.to_a.compact.pop end
Has a remote origin been setup?
# File lib/caretaker-core/git.rb, line 21 def git_remote_origin origin = execute_command('git config --get remote.origin.url') raise StandardError.new('remote.origin.url is not set - aborting') unless origin origin = origin.delete_suffix('.git') if origin.end_with?('.git') origin.gsub(':', '/').gsub('git@', 'https://') if origin.start_with?('git@') end
stuff
# File lib/caretaker-core/git.rb, line 52 def git_repo_details origin = git_remote_origin uri = URI.parse(origin) slug = uri.path.delete_prefix('/') repository = "https://#{uri.host}/#{slug}" [repository, slug] end
Setup the require global configuration
# File lib/caretaker-core/core.rb, line 27 def init_config(options) # Assign the default config config = DEFAULT_CONFIG # Merge in any user supplied options/config and return config.merge(options) end
This method reeks of :reek:NestedIterators
# File lib/caretaker-core/process.rb, line 16 def init_results(parsed) chronological = {} categorised = {} parsed.each do |tag| tag_str = tag.to_s chronological[tag_str] = [] categorised[tag_str] = {} CATEGORIES.each { |category, _array| categorised[tag_str][category.to_s] = [] } end [chronological, categorised] end
Limitations with regards to Pull Requests
-
Squished commits work as exepected and the contents of the child commmits is available
-
Rebased commits show as local commits as there is no way to see where they came from
-
Unsquished commits only show the PR commit_message as the child commits are ignored
This method reeks of :reek:TooManyStatements { max_statements: 6 }
# File lib/caretaker-core/core.rb, line 57 def parse_git_log_entries(config, log_entries) logs = {} tag = INITIAL_TAG log_entries.each do |line| tag, data = process_single_line(config, line, tag) (logs[tag] ||= []) << data if data end logs end
# File lib/caretaker-core/core.rb, line 133 def process_commit_message(commit_message, hash) patterns_array = [/Merge pull request #(\d+).*/, /\.*\(#(\d+)\)*\)/] patterns = Regexp.union(patterns_array) child_commit_messages = false commit_type = :pr if commit_message.scan(/Merge pull request #(\d+).*/m).size.positive? || commit_message.scan(/\.*\(#(\d+)\)*\)/m).size.positive? message, child_commit_messages = process_merge_request(commit_message, hash, patterns) else message, commit_type = process_normal_commit(commit_message) end [message, child_commit_messages, commit_type] end
# File lib/caretaker-core/core.rb, line 118 def process_merge_request(merge_message, hash, patterns) matches = merge_message.match(patterns).captures new_message = generate_pr_link(matches) child_commit_messages = get_child_messages(hash) [new_message, child_commit_messages] end
# File lib/caretaker-core/core.rb, line 128 def process_normal_commit(commit_message) commit_type = :commit [commit_message, commit_type] end
This method reeks of :reek:NestedIterators
# File lib/caretaker-core/process.rb, line 33 def process_results(parsed) chronological, categorised = init_results(parsed.keys) parsed.each do |tag, array| tag_str = tag.to_s array.each do |arr| (chronological[tag_str] ||= []) << arr (categorised[tag_str][arr[:category]] ||= []) << arr end end [chronological, categorised] end
# File lib/caretaker-core/core.rb, line 77 def process_single_line(config, line, tag) hash, hash_full, commit_message, child_commit_messages, commit_type, category, date, tag = get_parts(line, tag) return false if category.downcase == 'skip:' commit_message = commit_message.sub(/.*?:/, '').strip if config[:remove_categories] data = { :hash => hash, :hash_full => hash_full, :commit_message => commit_message, :child_commit_messages => child_commit_messages, :commit_type => commit_type, :category => category, :date => date } [tag, data] end
# File lib/caretaker-core/core.rb, line 35 def real_process(config) log_entries = retrieve_git_log_entries return [ [], [], [] ] unless log_entries parsed = parse_git_log_entries(config, log_entries) tags = generate_tag_list(parsed) chronological, categorised = process_results(parsed) [tags, chronological, categorised] end
comment to go here
# File lib/caretaker-core/git.rb, line 32 def retrieve_git_log_entries log_entries = execute_command("git log --first-parent --oneline --pretty=format:'%h|%H|%d|%s|%cs'") return false unless log_entries log_entries.split("\n") end
Make everything else private so it cannot be accessed directly
# File lib/caretaker-core/utils.rb, line 15 def split_log_entries(line, tag) hash, hash_full, refs, commit_message, date = line.split('|') tag = extract_tag(refs, tag) [date, hash, hash_full, commit_message, tag] end