debian-mirror-gitlab/lib/gitlab/template/base_template.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

148 lines
4.7 KiB
Ruby
Raw Normal View History

2019-02-15 15:39:39 +05:30
# frozen_string_literal: true
2016-06-22 15:30:34 +05:30
module Gitlab
module Template
class BaseTemplate
2018-12-13 13:39:08 +05:30
attr_accessor :category
2018-11-20 20:47:30 +05:30
def initialize(path, project = nil, category: nil)
2016-06-22 15:30:34 +05:30
@path = path
2018-11-20 20:47:30 +05:30
@category = category
2021-03-11 19:13:27 +05:30
@project = project
2016-09-13 17:45:13 +05:30
@finder = self.class.finder(project)
2016-06-22 15:30:34 +05:30
end
def name
File.basename(@path, self.class.extension)
end
2018-12-05 23:21:45 +05:30
alias_method :key, :name
2016-06-22 15:30:34 +05:30
2019-07-31 22:56:46 +05:30
def full_name
Pathname.new(@path)
.relative_path_from(self.class.base_dir)
.to_s
end
2016-06-22 15:30:34 +05:30
def content
2021-03-08 18:12:59 +05:30
blob = @finder.read(@path)
[description, blob].compact.join("\n")
end
def description
# override with a comment to be placed at the top of the blob.
2016-09-13 17:45:13 +05:30
end
2021-03-11 19:13:27 +05:30
def project_id
@project&.id
end
2018-12-05 23:21:45 +05:30
# Present for compatibility with license templates, which can replace text
# like `[fullname]` with a user-specified string. This is a no-op for
# other templates
def resolve!(_placeholders = {})
self
end
2020-03-13 15:44:24 +05:30
def to_json(*)
2018-12-05 23:21:45 +05:30
{ key: key, name: name, content: content }
2016-06-22 15:30:34 +05:30
end
2023-01-13 00:05:48 +05:30
alias_method :as_json, :to_json
2018-03-17 18:26:18 +05:30
def <=>(other)
name <=> other.name
end
2016-06-22 15:30:34 +05:30
class << self
2016-09-13 17:45:13 +05:30
def all(project = nil)
if categories.any?
categories.keys.flat_map { |cat| by_category(cat, project) }
else
by_category("", project)
end
2016-06-22 15:30:34 +05:30
end
2016-09-13 17:45:13 +05:30
def find(key, project = nil)
path = self.finder(project).find(key)
path.present? ? new(path, project) : nil
2016-06-22 15:30:34 +05:30
end
2016-09-13 17:45:13 +05:30
# Set categories as sub directories
# Example: { "category_name_1" => "directory_path_1", "category_name_2" => "directory_name_2" }
# Default is no category with all files in base dir of each class
2016-06-22 15:30:34 +05:30
def categories
2016-09-13 17:45:13 +05:30
{}
2016-06-22 15:30:34 +05:30
end
def extension
raise NotImplementedError
end
def base_dir
raise NotImplementedError
end
2016-09-13 17:45:13 +05:30
# Defines which strategy will be used to get templates files
2021-03-11 19:13:27 +05:30
# RepoTemplateFinder - Finds templates on project repository, templates are filtered per project
2016-09-13 17:45:13 +05:30
# GlobalTemplateFinder - Finds templates on gitlab installation source, templates can be used in all projects
def finder(project = nil)
raise NotImplementedError
2016-06-22 15:30:34 +05:30
end
2021-04-17 20:07:23 +05:30
def by_category(category, project = nil, empty_category_title: nil)
2016-09-13 17:45:13 +05:30
directory = category_directory(category)
files = finder(project).list_files_for(directory)
2021-04-17 20:07:23 +05:30
files.map { |f| new(f, project, category: category.presence || empty_category_title) }.sort
2016-06-22 15:30:34 +05:30
end
2016-09-13 17:45:13 +05:30
def category_directory(category)
return base_dir unless category.present?
2016-06-22 15:30:34 +05:30
2016-09-13 17:45:13 +05:30
File.join(base_dir, categories[category])
2016-06-22 15:30:34 +05:30
end
2021-03-11 19:13:27 +05:30
# `repository_template_names` - reads through Gitaly the actual templates names within a
# given project's repository. This is only used by issue and merge request templates,
# that need to call this once and then cache the returned value.
#
# `template_names` - is an alias to `repository_template_names`. It would read through
# Gitaly the actual template names within a given project's repository for all file templates
# other than `issue` and `merge request` description templates, which would instead
# overwrite the `template_names` method to return a redis cached version, by reading cached values
# from `repository.issue_template_names_hash` and `repository.merge_request_template_names_hash`
# methods.
def repository_template_names(project)
template_names_by_category(self.all(project))
end
alias_method :template_names, :repository_template_names
2016-06-22 15:30:34 +05:30
2021-03-11 19:13:27 +05:30
def template_names_by_category(items)
grouped = items.group_by(&:category)
categories = grouped.keys
categories.each_with_object({}) do |category, hash|
hash[category] = grouped[category].map do |item|
{ name: item.name, id: item.key, key: item.key, project_id: item.try(:project_id) }
end
2016-09-13 17:45:13 +05:30
end
2016-06-22 15:30:34 +05:30
end
2021-01-29 00:20:46 +05:30
def template_subsets(project = nil)
return [] if project && !project.repository.exists?
if categories.any?
2021-04-29 21:17:54 +05:30
categories.keys.to_h do |category|
2021-01-29 00:20:46 +05:30
files = self.by_category(category, project)
[category, files.map { |t| { key: t.key, name: t.name, content: t.content } }]
2021-04-29 21:17:54 +05:30
end
2021-01-29 00:20:46 +05:30
else
files = self.all(project)
files.map { |t| { key: t.key, name: t.name, content: t.content } }
end
end
2016-06-22 15:30:34 +05:30
end
end
end
end