app/helpers/diff_helper.rb
File `diff_helper.rb` has 253 lines of code (exceeds 250 allowed). Consider refactoring.module DiffHelper include CommitHelper MAX_LINES_WITHOUT_COLLAPSE = 50 Method `render_diff_stats` has 26 lines of code (exceeds 25 allowed). Consider refactoring. def render_diff_stats(options = {}) stats = options[:stats] diff = options[:diff] repo = options[:repo] commit = options[:commit] parent_commit = options[:common_ancestor] res = ["<ul class='list-group boffset0'>"] stats.each_with_index do |stat, ind| adds = stat.additions deletes = stat.deletions total = adds + deletes file_name = get_filename_in_diff(diff[ind], stat.filename) file_status = t "layout.projects.diff.#{get_file_status_in_diff(diff[ind])}" res << "<li class='list-group-item'>" res << "<div class='row'>" res << "<div class='col-sm-8'>" res << "<a href='#diff-#{ind}' data-toggle='tooltip' data-placement='top' title='#{file_status}'>" res << "#{diff_file_icon(diff[ind])} #{h(file_name)}" res << "</a></div>" res << render_file_changes(diff: diff[ind], adds: adds, deletes: deletes, total: total, repo: repo, commit: commit, parent_commit: parent_commit, file_status: file_status) res << "</div" res << "</li>" ind +=1 end res << "</ul>" wrap_diff_header_list(stats, res) end def wrap_diff_header_list(stats, list) is_stats_open = stats.count <= MAX_FILES_WITHOUT_COLLAPSE ? 'in' : '' res = ["<div class='panel-group' id='diff_header' role='tablist' aria-multiselectable='false'>"] res << "<div class='panel panel-default'>" res << "<div class='panel-heading' role='tab' id='heading'>" res << "<h4 class='panel-title'>" res << "<a data-toggle='collapse' data-parent='#diff_header' href='#collapseList' aria-expanded='true' aria-controls='collapseList'>" res << "<span class='fa fa-chevron-#{is_stats_open ? 'down' : 'up'}'></span>" res << " #{diff_header_message(stats)}</a>" res << "</h4>" res << "</div>" res << "<div id='collapseList' class='panel-collapse collapse #{is_stats_open}' role='tabpanel' aria-labelledby='collapseList'>" res << "<div class='panel-body'>" res += list res << "</div>" res << "</div>" res << "</div>" res << "</div>" res.join("\n").html_safe end def diff_header_message(stats) total_additions = stats.inject(0) {|sum, n| sum + n.additions} total_deletions = stats.inject(0) {|sum, n| sum + n.deletions} I18n.t('layout.projects.diff_show_header', files: t('layout.projects.commit_files_count', count: stats.count), additions: t('layout.projects.commit_additions_count', count: total_additions), deletions: t('layout.projects.commit_deletions_count', count: total_deletions)) end #include Git::Diff::InlineCallbackMethod `render_diff` has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring. def render_diff(diff, args = {})#diff_counter, comments, opts = nil diffpath = nil) if diff.respond_to?(:diff) diff, filepath, in_discussion = diff.diff, diff.a_path, false comments = (args[:comments] || []).select{|c| c.data.try('[]', :path) == filepath} else filepath, in_discussion, comments = args[:diffpath], true, args[:comments] end diff_display ||= Diff::Display::Unified.new(diff) url = if @pull @pull.id ? polymorphic_path([@project, @pull]) : '' elsif @commit commit_path @project, @commit end prepare(args.merge({filepath: filepath, comments: comments, in_discussion: in_discussion})) res = '<div class="table-responsive overflow-auto">' res << '<table class="table diff inline table-borderless" cellspacing="0" cellpadding="0">' res << '<tbody>' res << renderer(diff_display.data) #diff_display.render(Git::Diff::InlineCallback.new comments, path) res << tr_line_comments(comments) if in_discussion res << '</tbody>' res << '</table>' res << '</div>' res.html_safe end ######################################################## # FIXME: Just to dev, remove to lib. Really need it? ######################################################## def prepare(args) @url, @diff_counter, @in_discussion = args[:url], args[:diff_counter], args[:in_discussion] @filepath, @line_comments = args[:filepath], args[:comments] @diff_prefix = args[:diff_prefix] || 'diff' @add_reply_id, @num_line = if @in_discussion [@line_comments[0].id, @line_comments[0].data[:line].to_i - @line_comments[0].data[:strings].lines.count.to_i-1] else [nil, -1] end end def headerline(line) set_line_number "<tr class='header'> <td class='line_numbers'>...</td> <td class='line_numbers'>...</td> <td class='header'>#{line}</td> </tr>" end Similar blocks of code found in 2 locations. Consider refactoring. def addline(line) set_line_number "<tr class='changes'> <td class='line_numbers'></td> #{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number} <td class='code ins'> #{line_comment_icon} <pre ng-non-bindable>#{render_line(line)}</pre> </td> </tr> #{render_line_comments}" end Similar blocks of code found in 2 locations. Consider refactoring. def remline(line) set_line_number "<tr class='changes'> #{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number} <td class='line_numbers'></td> <td class='code del'> #{line_comment_icon} <pre ng-non-bindable>#{render_line(line)}</pre> </td> </tr> #{render_line_comments}" end Similar blocks of code found in 3 locations. Consider refactoring. def modline(line) set_line_number "<tr class='changes line'> #{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number} <td class='code unchanged modline'> #{line_comment_icon} <pre ng-non-bindable>#{render_line(line)}</pre> </td> </tr> #{render_line_comments}" end Similar blocks of code found in 3 locations. Consider refactoring. def unmodline(line) set_line_number "<tr class='changes unmodline'> #{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number} <td class='code unchanged unmodline'> #{line_comment_icon} <pre ng-non-bindable>#{render_line(line)}</pre> </td> </tr> #{render_line_comments}" end def sepline(line) "<tr class='changes hunk-sep'> <td class='line_numbers line_num_cut'>…</td> <td class='line_numbers line_num_cut'>…</td> <td class='code cut-line'></td> </tr>" end Similar blocks of code found in 3 locations. Consider refactoring. def nonewlineline(line) set_line_number "<tr class='changes'> #{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number} #{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number} <td class='code modline unmodline'> #{line_comment_icon} <pre ng-non-bindable>#{render_line(line)}</pre> </td> </tr> #{render_line_comments}" end def before_headerblock(block) end def after_headerblock(block) end def before_unmodblock(block) end def before_modblock(block) end def before_remblock(block) end def before_addblock(block) end def before_sepblock(block) end def before_nonewlineblock(block) end def after_unmodblock(block) end def after_modblock(block) end def after_remblock(block) end def after_addblock(block) end def after_sepblock(block) end def after_nonewlineblock(block) end def new_line "" end def renderer(data) result = [] data.each do |block| result << send("before_" + classify(block), block) result << block.map { |line| send(classify(line), line) } result << send("after_" + classify(block), block) end result.compact.join(new_line) end protected def classify(object) object.class.name[/\w+$/].downcase end def escape(str) str.to_s.gsub('&', '&').gsub('<', '<').gsub('>', '>').gsub('"', '"') end def render_line(line) res = '<span class="diff-content">' if line.inline_changes? prefix, changed, postfix = line.segments.map{|segment| escape(segment) } res << "#{prefix}<span class='idiff'>#{changed}</span>#{postfix}" else res << escape(line) end res << '</span>' res end def set_line_number @num_line = @num_line.succ end def line_comment_icon return if @no_commit_comment || (@in_discussion && @add_reply_id && @line_comments[0].data[:line].to_i != @num_line) if current_user link_to image_tag('line_comment.png', alt: t('layout.comments.new_header')), '#new_inline_comment', class: 'add_line-comment', 'ng-click' => "commentsCtrl.showInlineForm($event, #{new_inline_comment_params.to_json})" end end Method `render_line_comments` has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring. def render_line_comments unless @no_commit_comment || @in_discussion comments = @line_comments.select do |c| c.data.try('[]', :line).to_s == @num_line.to_s && c.actual_inline_comment? end tr_line_comments(comments) if comments.count > 0 end end def td_line_link id, num "<td class='line_numbers' id='#{id}'><a href='#{@url}##{id}'>#{num}</a></td>" end def tr_line_comments comments return if @no_commit_comment res="<tr class='line-comments'> <td class='line_numbers' colspan='2'>#{comments.count}</td> <td>" comments.each do |comment| res << "<div class='line-comment'> #{render 'projects/comments/comment', comment: comment, data: {project: @project, commentable: @commentable, add_anchor: 'inline', in_discussion: @in_discussion}} </div>" end if current_user res << link_to( t('layout.comments.new_inline'), '#new_inline_comment', class: 'btn btn-primary', 'ng-click' => "commentsCtrl.showInlineForm($event, #{new_inline_comment_params.to_json})", 'ng-hide' => "commentsCtrl.hideInlineCommentButton(#{new_inline_comment_params.to_json})" ) end res << "</td></tr>" end # def new_comment_path # hash = {path: @filepath, line: @num_line} # if @commentable.is_a? Issue # project_new_line_pull_comment_path(@project, @commentable, hash.merge({in_reply: @add_reply_id})) # elsif @commentable.is_a? Grit::Commit # new_line_commit_comment_path(@project, @commentable, hash) # end # end def new_inline_comment_params { path: @filepath, line: @num_line, in_reply: @add_reply_id } end end