# frozen_string_literal: true require 'shellwords' module PWN module Plugins # Used primarily in the past to clone local repos and generate an # html diff to be sent via email (deprecated). In the future this # plugin may be used to expand upon capabilities required w/ Git. module Git @@logger = PWN::Plugins::PWNLogger.create # Supported Method Parameters:: # PWN::Plugins::Git.gen_html_diff( # repo: 'required git repo name', # branch: 'required git repo branch (e.g. master, develop, etc)', # since: 'optional date, otherwise default to last pull' # ) public_class_method def self.gen_html_diff(opts = {}) git_repo_name = opts[:repo].to_s git_repo_branch = opts[:branch].to_s since_date = opts[:since] git_pull_output = '
' if since_date git_pull_output << "

#{git_repo_name}->#{git_repo_branch} Diff Summary Since #{since_date}

" git_entity = `git log --since #{since_date} --stat-width=65535 --graph`.to_s.scrub else git_pull_output << "

#{git_repo_name}->#{git_repo_branch} Diff Summary Since Last Pull

" git_entity = `git log ORIG_HEAD.. --stat-width=65535 --graph`.to_s.scrub end # For debugging purposes @@logger.info(git_entity) git_pull_output << git_entity.gsub("\n", '
') git_pull_output << '
' git_pull_output << '
' git_pull_output rescue StandardError => e raise e end # Supported Method Parameters:: # get_author_by_line_range( # repo_root: 'optional path to git repo root (defaults to ".")' # from_line: 'required line number to start in range', # to_line: 'required line number to stop in range', # target_file: 'require file in which line range is queried' # ) private_class_method def self.get_author_by_line_range(opts = {}) repo_root = if opts[:repo_root].nil? '.' else opts[:repo_root].to_s end from_line = opts[:from_line].to_i to_line = opts[:to_line].to_i target_file = opts[:target_file].to_s target_file.gsub!(%r{^#{repo_root}/}, '') if File.directory?(repo_root) && File.file?("#{repo_root}/#{target_file}") `git --git-dir="#{Shellwords.escape(repo_root)}/.git" log -L #{from_line},#{to_line}:"#{Shellwords.escape(target_file)}" | grep Author | head -n 1`.to_s.scrub else -1 end rescue StandardError => e raise e end # Supported Method Parameters:: # PWN::Plugins::Git.dump_all_repo_branches( # git_url: 'required git repo url' # ) public_class_method def self.dump_all_repo_branches(opts = {}) git_url = opts[:git_url].to_s.scrub `git ls-remote #{git_url}`.to_s.scrub rescue StandardError => e raise e end # Supported Method Parameters:: # get_author( # repo_root: dir_path, # from_line: line_no, # to_line:line_no, # target_file: entry, # entry_beautified: entry_beautified # ) public_class_method def self.get_author(opts = {}) repo_root = opts[:repo_root] from_line = opts[:from_line] to_line = opts[:to_line] target_file = opts[:target_file] entry_beautified = opts[:entry_beautified] # In order to get the original author # we need to query the original file # instead of the .JS-BEAUTIFIED file if entry_beautified target_file.gsub!(/\.JS-BEAUTIFIED$/, '') target_file_line_length = `wc -l #{target_file}`.split.first.to_i target_file_line_length = 1 if target_file_line_length < 1 # wc -l doesn't count line is \n is missing author = get_author_by_line_range( repo_root: repo_root, from_line: 1, to_line: target_file_line_length, target_file: target_file ) else if from_line.to_i && to_line.to_i < 1 from_line = 1 to_line = 1 end author = get_author_by_line_range( repo_root: repo_root, from_line: from_line, to_line: to_line, target_file: target_file ) end author rescue StandardError => e raise e end # Author(s):: Jacob Hoopes public_class_method def self.authors "AUTHOR(S): Jacob Hoopes " end # Display Usage for this Module public_class_method def self.help puts %{USAGE: git_html_resp = #{self}.gen_html_diff( repo: 'required git repo name', branch: 'required git repo branch (e.g. master, develop, etc)', since: 'optional date, otherwise default to last pull' ) author = #{self}.get_author( repo_root: 'optional path to git repo root (defaults to ".")' from_line: 'required line number to start in range', to_line: 'required line number to stop in range', target_file: 'required file in which line range is queried' entry_beautified: 'required boolean' ) all_repo_branches = #{self}.dump_all_repo_branches( git_url: 'required git repo url' ) #{self}.authors } end end end end