Commit 620d014a authored by Z.J. van de Weg's avatar Z.J. van de Weg Committed by Alfredo Sumaran

Implement backend gitlab ci dropdown

This commit builds on the groundwork in
ee008e300b1ec0abcc90e6a30816ec0754cea0dd, which refactored the backend
so the same code could be used for new dropdowns. In this commit its
used for templates for the `.gitlab-ci.yml` files.
parent 567f6a7b
......@@ -186,10 +186,16 @@ module BlobHelper
end
def gitignore_names
return @gitignore_names if defined?(@gitignore_names)
@gitignore_names ||=
Gitlab::Template::Gitignore.categories.keys.map do |k|
[k, Gitlab::Template::Gitignore.by_category(k).map { |t| { name: t.name } }]
end.to_h
end
@gitignore_names = Gitlab::Template::Gitignore.categories.map do |k, _|
[k, Gitlab::Template::Gitignore.by_category(k)]
def gitlab_ci_ymls
@gitlab_ci_ymls ||=
Gitlab::Template::GitlabCIYml.categories.keys.map do |k|
[k, Gitlab::Template::GitlabCIYml.by_category(k).map { |t| { name: t.name } }]
end.to_h
end
end
module API
class Templates < Grape::API
TEMPLATE_TYPES = {
gitignores: Gitlab::Template::Gitignore
gitignores: Gitlab::Template::Gitignore,
gitlab_ci_ymls: Gitlab::Template::GitlabCIYml
}.freeze
TEMPLATE_TYPES.each do |template, klass|
......
......@@ -13,40 +13,53 @@ module Gitlab
File.read(@path)
end
def categories
raise NotImplementedError
end
def extension
raise NotImplementedError
end
def base_dir
raise NotImplementedError
end
class << self
def all
self.category_directories.flat_map do |dir|
templates_for_folder(dir)
end
self.categories.keys.flat_map { |cat| by_category(cat) }
end
def find(key)
file_name = "#{key}#{self.extension}"
directory = select_directory(file_name)
directory ? new(File.join(directory, file_name)) : nil
directory ? new(File.join(category_directory(directory), file_name)) : nil
end
def by_category(category)
templates_for_folder(categories[category])
templates_for_directory(category_directory(category))
end
def category_directories
self.categories.values.map { |subdir| File.join(base_dir, subdir)}
def category_directory(category)
File.join(base_dir, categories[category])
end
private
def select_directory(file_name)
category_directories.find { |dir| File.exist?(File.join(dir, file_name)) }
categories.keys.find do |category|
File.exist?(File.join(category_directory(category), file_name))
end
end
def templates_for_folder(dir)
Dir.glob("#{dir.to_s}/*#{self.extension}").select { |f| f =~ filter_regex }.map { |f| new(f) }
def templates_for_directory(dir)
dir << '/' unless dir.end_with?('/')
Dir.glob(File.join(dir, "*#{self.extension}")).select { |f| f =~ filter_regex }.map { |f| new(f) }
end
def filter_regex
/#{Regexp.escape(extension)}\z/
@filter_reges ||= /#{Regexp.escape(extension)}\z/
end
end
end
......
module Gitlab
module Template
class Gitignore < BaseTemplate
class << self
def extension
'.gitignore'
......@@ -9,8 +8,8 @@ module Gitlab
def categories
{
Languages: '',
Global: 'Global'
"Languages" => '',
"Global" => 'Global'
}
end
......
module Gitlab
module Template
class GitlabCIYml < BaseTemplate
class << self
def extension
'.gitlab-ci.yml'
end
def categories
{
"General" => '',
"Pages" =>'Pages'
}
end
def base_dir
Rails.root.join('vendor/gitlab-ci-yml')
end
end
end
end
end
namespace :gitlab do
desc "GitLab | Update templates"
task :update_templates do
update("gitignore")
update("gitlab-ci-yml")
TEMPLATE_DATA.each { |template| update(template) }
end
def update(directory)
unless clone_repository(directory)
puts "Cloning the #{directory} templates failed".red
def update(template)
sub_dir = template.repo_url.match(/([a-z-]+)\.git\z/)[1]
dir = File.join(vendor_directory, sub_dir)
unless clone_repository(template.repo_url, dir)
puts "Cloning the #{sub_dir} templates failed".red
return
end
remove_unneeded_files(directory)
remove_unneeded_files(dir, template.cleanup_regex)
puts "Done".green
end
def clone_repository(directory)
dir = File.join(vendor_directory, directory)
FileUtils.rm_rf(dir) if Dir.exist?(dir)
FileUtils.cd vendor_directory
def clone_repository(url, directory)
FileUtils.rm_rf(directory) if Dir.exist?(directory)
system("git clone --depth=1 --branch=master #{TEMPLATE_DATA[directory]}")
system("git clone #{url} --depth=1 --branch=master #{directory}")
end
# Retain only certain files:
# - The LICENSE, because we have to
# - The sub dir global
# - The gitignores themself
# - The sub dirs so we can organise the file by category
# - The templates themself
# - Dir.entires returns also the entries '.' and '..'
def remove_unneeded_files(directory)
regex = CLEANUP_REGEX[directory]
def remove_unneeded_files(directory, regex)
Dir.foreach(directory) do |file|
FileUtils.rm_rf(File.join(directory, file)) unless file =~ regex
end
......@@ -37,25 +36,17 @@ namespace :gitlab do
private
TEMPLATE_DATA = {
"gitignore" => "https://github.com/github/gitignore.git",
"gitlab-ci-yml" => "https://gitlab.com/gitlab-org/gitlab-ci-yml.git"
}.freeze
CLEANUP_REGEX = {
"gitignore" => /(\.{1,2}|LICENSE|Global|\.gitignore)\z/,
"gitlab-ci-yml" => /(\.{1,2}|LICENSE|Pages|\.gitignore)\z/
}.freeze
Template = Struct.new(:repo_url, :cleanup_regex)
TEMPLATE_DATA = [Template.new(
"https://github.com/github/gitignore.git",
/(\.{1,2}|LICENSE|Global|\.gitignore)\z/
),
Template.new(
"https://gitlab.com/gitlab-org/gitlab-ci-yml.git",
/(\.{1,2}|LICENSE|Pages|\.gitignore)\z/
)]
def vendor_directory
Rails.root.join('vendor')
end
def gitignore_directory
File.join(vendor_directory, 'gitignore')
end
def gitlab_ci_directory
File.join(vendor_directory, 'gitlab-ci')
end
end
......@@ -3,22 +3,23 @@ require 'spec_helper'
describe API::Templates, api: true do
include ApiHelpers
describe 'Entity Gitignore' do
describe 'the Template Entity' do
before { get api('/gitignores/Ruby') }
it { expect(json_response['name']).to eq('Ruby') }
it { expect(json_response['content']).to include('*.gem') }
end
describe 'Entity GitignoresList' do
describe 'the TemplateList Entity' do
before { get api('/gitignores') }
it { expect(json_response.first['name']).not_to be_nil }
it { expect(json_response.first['content']).to be_nil }
end
context 'requesting gitignores' do
describe 'GET /gitignores' do
it 'returns a list of available license templates' do
it 'returns a list of available gitignore templates' do
get api('/gitignores')
expect(response.status).to eq(200)
......@@ -26,4 +27,17 @@ describe API::Templates, api: true do
expect(json_response.size).to be > 15
end
end
end
context 'requesting gitlab-ci-ymls' do
describe 'GET /gitlab_ci_ymls' do
it 'returns a list of available gitlab_ci_ymls' do
get api('/gitlab_ci_ymls')
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).not_to be_nil
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment