commits_helper.rb 7.04 KB
Newer Older
gitlabhq's avatar
gitlabhq committed
1
module CommitsHelper
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
  # Returns a link to the commit author. If the author has a matching user and
  # is a member of the current @project it will link to the team member page.
  # Otherwise it will link to the author email as specified in the commit.
  #
  # options:
  #  avatar: true will prepend the avatar image
  #  size:   size of the avatar image in px
  def commit_author_link(commit, options = {})
    commit_person_link(commit, options.merge(source: :author))
  end

  # Just like #author_link but for the committer.
  def commit_committer_link(commit, options = {})
    commit_person_link(commit, options.merge(source: :committer))
  end

18 19
  def image_diff_class(diff)
    if diff.deleted_file
20
      "deleted"
21
    elsif diff.new_file
22
      "added"
23 24 25 26
    else
      nil
    end
  end
27

28 29 30 31 32
  def commit_to_html(commit, ref, project)
    render 'projects/commits/commit',
      commit: commit,
      ref: ref,
      project: project
33
  end
34

35 36 37 38 39 40
  # Breadcrumb links for a Project and, if applicable, a tree path
  def commits_breadcrumbs
    return unless @project && @ref

    # Add the root project link and the arrow icon
    crumbs = content_tag(:li) do
Vinnie Okada's avatar
Vinnie Okada committed
41 42 43 44
      link_to(
        @project.path,
        namespace_project_commits_path(@project.namespace, @project, @ref)
      )
45 46 47 48 49 50
    end

    if @path
      parts = @path.split('/')

      parts.each_with_index do |part, i|
51
        crumbs << content_tag(:li) do
52
          # The text is just the individual part, but the link needs all the parts before it
Vinnie Okada's avatar
Vinnie Okada committed
53 54 55 56 57 58 59 60
          link_to(
            part,
            namespace_project_commits_path(
              @project.namespace,
              @project,
              tree_join(@ref, parts[0..i].join('/'))
            )
          )
61 62 63 64 65 66 67
        end
      end
    end

    crumbs.html_safe
  end

68 69 70 71 72 73 74 75
  # Return Project default branch, if it present in array
  # Else - first branch in array (mb last actual branch)
  def commit_default_branch(project, branches)
    branches.include?(project.default_branch) ? branches.delete(project.default_branch) : branches.pop
  end

  # Returns the sorted alphabetically links to branches, separated by a comma
  def commit_branches_links(project, branches)
76
    branches.sort.map do |branch|
Vinnie Okada's avatar
Vinnie Okada committed
77 78 79
      link_to(
        namespace_project_tree_path(project.namespace, project, branch)
      ) do
80
        content_tag :span, class: 'label label-gray' do
81
          icon('code-fork') + ' ' + branch
82 83 84
        end
      end
    end.join(" ").html_safe
85 86
  end

87 88 89
  # Returns the sorted links to tags, separated by a comma
  def commit_tags_links(project, tags)
    sorted = VersionSorter.rsort(tags)
90
    sorted.map do |tag|
Vinnie Okada's avatar
Vinnie Okada committed
91 92 93 94
      link_to(
        namespace_project_commits_path(project.namespace, project,
                                       project.repository.find_tag(tag).name)
      ) do
95
        content_tag :span, class: 'label label-gray' do
96
          icon('tag') + ' ' + tag
97 98 99
        end
      end
    end.join(" ").html_safe
100 101
  end

102
  def link_to_browse_code(project, commit)
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
    if @path.blank?
      return link_to(
        "Browse Files",
        namespace_project_tree_path(project.namespace, project, commit),
        class: "btn btn-default"
      )
    end

    return unless current_controller?(:projects, :commits)

    if @repo.blob_at(commit.id, @path)
      return link_to(
        "Browse File",
        namespace_project_blob_path(project.namespace, project,
                                    tree_join(commit.id, @path)),
        class: "btn btn-default"
      )
    elsif @path.present?
      return link_to(
        "Browse Directory",
        namespace_project_tree_path(project.namespace, project,
                                    tree_join(commit.id, @path)),
        class: "btn btn-default"
      )
127 128 129
    end
  end

130
  def revert_commit_link(commit, continue_to_path, btn_class: nil, has_tooltip: true)
131
    commit_action_link('revert', commit, continue_to_path, btn_class: btn_class, has_tooltip: has_tooltip)
132 133
  end

134
  def cherry_pick_commit_link(commit, continue_to_path, btn_class: nil, has_tooltip: true)
135
    commit_action_link('cherry-pick', commit, continue_to_path, btn_class: btn_class, has_tooltip: has_tooltip)
136 137
  end

138 139 140 141 142 143 144 145 146 147 148
  protected

  # Private: Returns a link to a person. If the person has a matching user and
  # is a member of the current @project it will link to the team member page.
  # Otherwise it will link to the person email as specified in the commit.
  #
  # options:
  #  source: one of :author or :committer
  #  avatar: true will prepend the avatar image
  #  size:   size of the avatar image in px
  def commit_person_link(commit, options = {})
149
    user = commit.send(options[:source])
150

151 152
    source_name = clean(commit.send "#{options[:source]}_name".to_sym)
    source_email = clean(commit.send "#{options[:source]}_email".to_sym)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
153

154
    person_name = user.try(:name) || source_name
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
155

156 157
    text =
      if options[:avatar]
Phil Hughes's avatar
Phil Hughes committed
158
        %Q{<span class="commit-#{options[:source]}-name">#{person_name}</span>}
159 160 161
      else
        person_name
      end
162

163
    options = {
164
      class: "commit-#{options[:source]}-link has-tooltip",
165
      title: source_email
166 167
    }

168
    if user.nil?
169
      mail_to(source_email, text.html_safe, options)
170
    else
171
      link_to(text.html_safe, user_path(user), options)
172 173
    end
  end
174

175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
  def commit_action_link(action, commit, continue_to_path, btn_class: nil, has_tooltip: true)
    return unless current_user

    tooltip = "#{action.capitalize} this #{commit.change_type_title(current_user)} in a new merge request" if has_tooltip
    btn_class = "btn btn-#{btn_class}" unless btn_class.nil?

    if can_collaborate_with_project?
      link_to action.capitalize, "#modal-#{action}-commit", 'data-toggle' => 'modal', 'data-container' => 'body', title: (tooltip if has_tooltip), class: "#{btn_class} #{'has-tooltip' if has_tooltip}"
    elsif can?(current_user, :fork_project, @project)
      continue_params = {
        to: continue_to_path,
        notice: "#{edit_in_new_fork_notice} Try to #{action} this commit again.",
        notice_now: edit_in_new_fork_notice_now
      }
      fork_path = namespace_project_forks_path(@project.namespace, @project,
        namespace_key: current_user.namespace.id,
        continue: continue_params)

      link_to action.capitalize, fork_path, class: btn_class, method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: (tooltip if has_tooltip)
    end
  end

197
  def view_file_btn(commit_sha, diff_new_path, project)
Vinnie Okada's avatar
Vinnie Okada committed
198 199
    link_to(
      namespace_project_blob_path(project.namespace, project,
200
                                  tree_join(commit_sha, diff_new_path)),
201
      class: 'btn view-file js-view-file'
Vinnie Okada's avatar
Vinnie Okada committed
202
    ) do
skv's avatar
skv committed
203 204 205 206
      raw('View file @') + content_tag(:span, commit_sha[0..6],
                                       class: 'commit-short-id')
    end
  end
207 208 209 210

  def truncate_sha(sha)
    Commit.truncate_sha(sha)
  end
211 212 213 214

  def clean(string)
    Sanitize.clean(string, remove_contents: true)
  end
215 216 217 218 219 220 221 222 223 224 225

  def limited_commits(commits)
    if commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
      [
        commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE),
        commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE
      ]
    else
      [commits, 0]
    end
  end
gitlabhq's avatar
gitlabhq committed
226
end