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.
This commit is contained in:
Z.J. van de Weg 2016-06-02 18:20:08 +02:00 committed by Alfredo Sumaran
parent 567f6a7b42
commit 620d014aef
8 changed files with 126 additions and 80 deletions

View file

@ -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)]
end.to_h
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

View file

@ -1,7 +1,8 @@
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|

View file

@ -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

View file

@ -1,7 +1,6 @@
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

View file

@ -0,0 +1,22 @@
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

View file

@ -1,35 +1,34 @@
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

View file

@ -1,29 +0,0 @@
require 'spec_helper'
describe API::Templates, api: true do
include ApiHelpers
describe 'Entity Gitignore' 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
before { get api('/gitignores') }
it { expect(json_response.first['name']).not_to be_nil }
it { expect(json_response.first['content']).to be_nil }
end
describe 'GET /gitignores' do
it 'returns a list of available license templates' do
get api('/gitignores')
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response.size).to be > 15
end
end
end

View file

@ -0,0 +1,43 @@
require 'spec_helper'
describe API::Templates, api: true do
include ApiHelpers
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 '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 gitignore templates' do
get api('/gitignores')
expect(response.status).to eq(200)
expect(json_response).to be_an Array
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