diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 2d42cce95ce..b30a01614be 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -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 diff --git a/lib/api/templates.rb b/lib/api/templates.rb index 4c770c0b9dd..9f5f10a5088 100644 --- a/lib/api/templates.rb +++ b/lib/api/templates.rb @@ -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| diff --git a/lib/gitlab/template/base_template.rb b/lib/gitlab/template/base_template.rb index e1cdfc8f5f6..652a496b57b 100644 --- a/lib/gitlab/template/base_template.rb +++ b/lib/gitlab/template/base_template.rb @@ -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 diff --git a/lib/gitlab/template/gitignore.rb b/lib/gitlab/template/gitignore.rb index 73fb3b18c4d..964fbfd4de3 100644 --- a/lib/gitlab/template/gitignore.rb +++ b/lib/gitlab/template/gitignore.rb @@ -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 diff --git a/lib/gitlab/template/gitlab_ci_yml.rb b/lib/gitlab/template/gitlab_ci_yml.rb new file mode 100644 index 00000000000..20377499ac9 --- /dev/null +++ b/lib/gitlab/template/gitlab_ci_yml.rb @@ -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 diff --git a/lib/tasks/gitlab/update_templates.rake b/lib/tasks/gitlab/update_templates.rake index 36ffad8aae9..90b1a64ed5a 100644 --- a/lib/tasks/gitlab/update_templates.rake +++ b/lib/tasks/gitlab/update_templates.rake @@ -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 diff --git a/spec/requests/api/gitignores_spec.rb b/spec/requests/api/gitignores_spec.rb deleted file mode 100644 index 9130312c057..00000000000 --- a/spec/requests/api/gitignores_spec.rb +++ /dev/null @@ -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 diff --git a/spec/requests/api/templates_spec.rb b/spec/requests/api/templates_spec.rb new file mode 100644 index 00000000000..0e9a28b1ff6 --- /dev/null +++ b/spec/requests/api/templates_spec.rb @@ -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