Module: TreeHelper

Constant Summary collapse

FILE_LIMIT =
1_000

Instance Method Summary collapse

Instance Method Details


158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'app/helpers/tree_helper.rb', line 158

def breadcrumb_data_attributes
  attrs = {
    can_collaborate: can_collaborate_with_project?(@project).to_s,
    new_blob_path: project_new_blob_path(@project, @ref),
    upload_path: project_create_blob_path(@project, @ref),
    new_dir_path: project_create_dir_path(@project, @ref),
    new_branch_path: new_project_branch_path(@project),
    new_tag_path: new_project_tag_path(@project),
    can_edit_tree: can_edit_tree?.to_s
  }

  if can?(current_user, :fork_project, @project) && can?(current_user, :create_merge_request_in, @project)
    continue_param = {
      to: project_new_blob_path(@project, @id),
      notice: edit_in_new_fork_notice,
      notice_now: edit_in_new_fork_notice_now
    }

    attrs.merge!(
      fork_new_blob_path: project_forks_path(@project, namespace_key: current_user.namespace.id, continue: continue_param),
      fork_new_directory_path: project_forks_path(@project, namespace_key: current_user.namespace.id, continue: continue_param.merge({
        to: request.fullpath,
        notice: _("%{edit_in_new_fork_notice} Try to create a new directory again.") % { edit_in_new_fork_notice: edit_in_new_fork_notice }
      })),
      fork_upload_blob_path: project_forks_path(@project, namespace_key: current_user.namespace.id, continue: continue_param.merge({
        to: request.fullpath,
        notice: _("%{edit_in_new_fork_notice} Try to upload a file again.") % { edit_in_new_fork_notice: edit_in_new_fork_notice }
      }))
    )
  end

  attrs
end

#can_edit_tree?(project = nil, ref = nil) ⇒ Boolean

Returns:

  • (Boolean)

60
61
62
63
64
65
66
67
# File 'app/helpers/tree_helper.rb', line 60

def can_edit_tree?(project = nil, ref = nil)
  project ||= @project
  ref ||= @ref

  return false unless on_top_of_branch?(project, ref)

  can_collaborate_with_project?(project, ref: ref)
end

#commit_in_fork_helpObject


102
103
104
# File 'app/helpers/tree_helper.rb', line 102

def commit_in_fork_help
  _("A new branch will be created in your fork and a new merge request will be started.")
end

#commit_in_single_accessible_branchObject


106
107
108
109
110
111
112
113
# File 'app/helpers/tree_helper.rb', line 106

def commit_in_single_accessible_branch
  branch_name = ERB::Util.html_escape(selected_branch)

  message = _("Your changes can be committed to %{branch_name} because a merge "\
              "request is open.") % { branch_name: "<strong>#{branch_name}</strong>" }

  message.html_safe
end

204
205
206
207
208
209
210
211
# File 'app/helpers/tree_helper.rb', line 204

def directory_download_links(project, ref, archive_prefix)
  Gitlab::Workhorse::ARCHIVE_FORMATS.map do |fmt|
    {
      text: fmt,
      path: project_archive_path(project, id: tree_join(ref, archive_prefix), format: fmt)
    }
  end
end

#edit_in_new_fork_noticeObject


93
94
95
96
# File 'app/helpers/tree_helper.rb', line 93

def edit_in_new_fork_notice
  _("You're not allowed to make changes to this project directly. "\
    "A fork of this project has been created that you can make changes in, so you can submit a merge request.")
end

#edit_in_new_fork_notice_action(action) ⇒ Object


98
99
100
# File 'app/helpers/tree_helper.rb', line 98

def edit_in_new_fork_notice_action(action)
  edit_in_new_fork_notice + _(" Try to %{action} this file again.") % { action: action }
end

#edit_in_new_fork_notice_nowObject


88
89
90
91
# File 'app/helpers/tree_helper.rb', line 88

def edit_in_new_fork_notice_now
  _("You're not allowed to make changes to this project directly. "\
    "A fork of this project is being created that you can make changes in, so you can submit a merge request.")
end

#fast_project_blob_path(project, blob_path) ⇒ Object

Using Rails `*_path` methods can be slow, especially when generating many paths, as with a repository tree that has thousands of items.


39
40
41
42
43
# File 'app/helpers/tree_helper.rb', line 39

def fast_project_blob_path(project, blob_path)
  ActionDispatch::Journey::Router::Utils.escape_path(
    File.join(relative_url_root, project.path_with_namespace, '-', 'blob', blob_path)
  )
end

#fast_project_tree_path(project, tree_path) ⇒ Object


45
46
47
48
49
# File 'app/helpers/tree_helper.rb', line 45

def fast_project_tree_path(project, tree_path)
  ActionDispatch::Journey::Router::Utils.escape_path(
    File.join(relative_url_root, project.path_with_namespace, '-', 'tree', tree_path)
  )
end

#flatten_tree(root_path, tree) ⇒ Object

returns the relative path of the first subdir that doesn't have only one directory descendant


139
140
141
# File 'app/helpers/tree_helper.rb', line 139

def flatten_tree(root_path, tree)
  tree.flat_path.sub(%r{\A#{Regexp.escape(root_path)}/}, '')
end

#on_top_of_branch?(project = @project, ref = @ref) ⇒ Boolean

Returns:

  • (Boolean)

56
57
58
# File 'app/helpers/tree_helper.rb', line 56

def on_top_of_branch?(project = @project, ref = @ref)
  project.repository.branch_exists?(ref)
end

#path_breadcrumbs(max_links = 6) ⇒ Object


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'app/helpers/tree_helper.rb', line 115

def path_breadcrumbs(max_links = 6)
  if @path.present?
    part_path = ""
    parts = @path.split('/')

    yield('..', File.join(*parts.first(parts.count - 2))) if parts.count > max_links

    parts.each do |part|
      part_path = File.join(part_path, part) unless part_path.empty?
      part_path = part if part_path.empty?

      next if parts.count > max_links && !parts.last(2).include?(part)

      yield(part, part_path)
    end
  end
end

#relative_url_rootObject


147
148
149
# File 'app/helpers/tree_helper.rb', line 147

def relative_url_root
  Gitlab.config.gitlab.relative_url_root.presence || '/'
end

#render_tree(tree) ⇒ Object

Sorts a repository's tree so that folders are before files and renders their corresponding partials

tree - A `Tree` object for the current tree rubocop: disable CodeReuse/ActiveRecord


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'app/helpers/tree_helper.rb', line 11

def render_tree(tree)
  # Sort submodules and folders together by name ahead of files
  folders, files, submodules = tree.trees, tree.blobs, tree.submodules
  tree = []
  items = (folders + submodules).sort_by(&:name) + files

  if items.size > FILE_LIMIT
    tree << render(partial: 'projects/tree/truncated_notice_tree_row',
                   locals: { limit: FILE_LIMIT, total: items.size })
    items = items.take(FILE_LIMIT)
  end

  tree << render(partial: 'projects/tree/tree_row', collection: items) if items.present?
  tree.join.html_safe
end

#selected_branchObject


143
144
145
# File 'app/helpers/tree_helper.rb', line 143

def selected_branch
  @branch_name || tree_edit_branch
end

#tree_content_data(logs_path, project, path) ⇒ Object

project and path are used on the EE version


152
153
154
155
156
# File 'app/helpers/tree_helper.rb', line 152

def tree_content_data(logs_path, project, path)
  {
    "logs-path" => logs_path
  }
end

#tree_edit_branch(project = @project, ref = @ref) ⇒ Object


69
70
71
72
73
74
75
76
77
78
# File 'app/helpers/tree_helper.rb', line 69

def tree_edit_branch(project = @project, ref = @ref)
  return unless can_edit_tree?(project, ref)

  if user_access(project).can_push_to_branch?(ref)
    ref
  else
    project = tree_edit_project(project)
    project.repository.next_branch('patch')
  end
end

#tree_edit_project(project = @project) ⇒ Object


80
81
82
83
84
85
86
# File 'app/helpers/tree_helper.rb', line 80

def tree_edit_project(project = @project)
  if can?(current_user, :push_code, project)
    project
  elsif current_user && current_user.already_forked?(project)
    current_user.fork_of(project)
  end
end

#tree_icon(type, mode, name) ⇒ Object

Return an image icon depending on the file type and mode

type - String type of the tree item; either 'folder' or 'file' mode - File unix mode name - File name


33
34
35
# File 'app/helpers/tree_helper.rb', line 33

def tree_icon(type, mode, name)
  icon([file_type_icon_class(type, mode, name), 'fw'])
end

#tree_join(*args) ⇒ Object

Simple shortcut to File.join


52
53
54
# File 'app/helpers/tree_helper.rb', line 52

def tree_join(*args)
  File.join(*args)
end

#up_dir_pathObject


133
134
135
136
# File 'app/helpers/tree_helper.rb', line 133

def up_dir_path
  file = File.join(@path, "..")
  tree_join(@ref, file)
end

#vue_file_list_data(project, ref) ⇒ Object


192
193
194
195
196
197
198
199
200
201
202
# File 'app/helpers/tree_helper.rb', line 192

def vue_file_list_data(project, ref)
  {
    can_push_code: current_user&.can?(:push_code, project) && "true",
    project_path: project.full_path,
    project_short_path: project.path,
    fork_path: current_user&.fork_of(project)&.full_path,
    ref: ref,
    escaped_ref: ActionDispatch::Journey::Router::Utils.escape_path(ref),
    full_name: project.name_with_namespace
  }
end