From 27bf7ae59eb95bff0254b8ad3c001ea2397ec544 Mon Sep 17 00:00:00 2001 From: ZJ van de Weg Date: Fri, 27 May 2016 11:00:56 +0200 Subject: Refactor Gitlab::Gitignores --- app/helpers/blob_helper.rb | 8 ++-- lib/api/api.rb | 2 +- lib/api/entities.rb | 4 +- lib/api/gitignores.rb | 29 -------------- lib/api/templates.rb | 35 +++++++++++++++++ lib/gitlab/gitignore.rb | 56 --------------------------- lib/gitlab/template/base_template.rb | 54 ++++++++++++++++++++++++++ lib/gitlab/template/gitignore.rb | 23 +++++++++++ lib/tasks/gitlab/update_gitignore.rake | 46 ---------------------- lib/tasks/gitlab/update_templates.rake | 61 ++++++++++++++++++++++++++++++ spec/lib/gitlab/gitignore_spec.rb | 40 -------------------- spec/lib/gitlab/template/gitignore_spec.rb | 40 ++++++++++++++++++++ spec/requests/api/gitignores_spec.rb | 2 +- 13 files changed, 220 insertions(+), 180 deletions(-) delete mode 100644 lib/api/gitignores.rb create mode 100644 lib/api/templates.rb delete mode 100644 lib/gitlab/gitignore.rb create mode 100644 lib/gitlab/template/base_template.rb create mode 100644 lib/gitlab/template/gitignore.rb delete mode 100644 lib/tasks/gitlab/update_gitignore.rake create mode 100644 lib/tasks/gitlab/update_templates.rake delete mode 100644 spec/lib/gitlab/gitignore_spec.rb create mode 100644 spec/lib/gitlab/template/gitignore_spec.rb diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 5b54b34070c..2d42cce95ce 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -188,10 +188,8 @@ module BlobHelper def gitignore_names return @gitignore_names if defined?(@gitignore_names) - @gitignore_names = { - Global: Gitlab::Gitignore.global.map { |gitignore| { name: gitignore.name } }, - # Note that the key here doesn't cover it really - Languages: Gitlab::Gitignore.languages_frameworks.map{ |gitignore| { name: gitignore.name } } - } + @gitignore_names = Gitlab::Template::Gitignore.categories.map do |k, _| + [k, Gitlab::Template::Gitignore.by_category(k)] + end.to_h end end diff --git a/lib/api/api.rb b/lib/api/api.rb index 0e7a1cc2623..f8f680a6311 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -33,7 +33,6 @@ module API mount ::API::Commits mount ::API::DeployKeys mount ::API::Files - mount ::API::Gitignores mount ::API::GroupMembers mount ::API::Groups mount ::API::Internal @@ -58,6 +57,7 @@ module API mount ::API::Subscriptions mount ::API::SystemHooks mount ::API::Tags + mount ::API::Templates mount ::API::Triggers mount ::API::Users mount ::API::Variables diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 2e397643ed1..0c9fc5604fd 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -472,11 +472,11 @@ module API expose :content end - class GitignoresList < Grape::Entity + class TemplatesList < Grape::Entity expose :name end - class Gitignore < Grape::Entity + class Template < Grape::Entity expose :name, :content end end diff --git a/lib/api/gitignores.rb b/lib/api/gitignores.rb deleted file mode 100644 index 270c9501dd2..00000000000 --- a/lib/api/gitignores.rb +++ /dev/null @@ -1,29 +0,0 @@ -module API - class Gitignores < Grape::API - - # Get the list of the available gitignore templates - # - # Example Request: - # GET /gitignores - get 'gitignores' do - present Gitlab::Gitignore.all, with: Entities::GitignoresList - end - - # Get the text for a specific gitignore - # - # Parameters: - # name (required) - The name of a license - # - # Example Request: - # GET /gitignores/Elixir - # - get 'gitignores/:name' do - required_attributes! [:name] - - gitignore = Gitlab::Gitignore.find(params[:name]) - not_found!('.gitignore') unless gitignore - - present gitignore, with: Entities::Gitignore - end - end -end diff --git a/lib/api/templates.rb b/lib/api/templates.rb new file mode 100644 index 00000000000..4c770c0b9dd --- /dev/null +++ b/lib/api/templates.rb @@ -0,0 +1,35 @@ +module API + class Templates < Grape::API + TEMPLATE_TYPES = { + gitignores: Gitlab::Template::Gitignore + }.freeze + + TEMPLATE_TYPES.each do |template, klass| + # Get the list of the available template + # + # Example Request: + # GET /gitignores + # GET /gitlab_ci_ymls + get template.to_s do + present klass.all, with: Entities::TemplatesList + end + + # Get the text for a specific template + # + # Parameters: + # name (required) - The name of a template + # + # Example Request: + # GET /gitignores/Elixir + # GET /gitlab_ci_ymls/Ruby + get "#{template}/:name" do + required_attributes! [:name] + + new_template = klass.find(params[:name]) + not_found!("#{template.to_s.singularize}") unless new_template + + present new_template, with: Entities::Template + end + end + end +end diff --git a/lib/gitlab/gitignore.rb b/lib/gitlab/gitignore.rb deleted file mode 100644 index f46b43b61a4..00000000000 --- a/lib/gitlab/gitignore.rb +++ /dev/null @@ -1,56 +0,0 @@ -module Gitlab - class Gitignore - FILTER_REGEX = /\.gitignore\z/.freeze - - def initialize(path) - @path = path - end - - def name - File.basename(@path, '.gitignore') - end - - def content - File.read(@path) - end - - class << self - def all - languages_frameworks + global - end - - def find(key) - file_name = "#{key}.gitignore" - - directory = select_directory(file_name) - directory ? new(File.join(directory, file_name)) : nil - end - - def global - files_for_folder(global_dir).map { |file| new(File.join(global_dir, file)) } - end - - def languages_frameworks - files_for_folder(gitignore_dir).map { |file| new(File.join(gitignore_dir, file)) } - end - - private - - def select_directory(file_name) - [gitignore_dir, global_dir].find { |dir| File.exist?(File.join(dir, file_name)) } - end - - def global_dir - File.join(gitignore_dir, 'Global') - end - - def gitignore_dir - Rails.root.join('vendor/gitignore') - end - - def files_for_folder(dir) - Dir.glob("#{dir.to_s}/*.gitignore").map { |file| file.gsub(FILTER_REGEX, '') } - end - end - end -end diff --git a/lib/gitlab/template/base_template.rb b/lib/gitlab/template/base_template.rb new file mode 100644 index 00000000000..e1cdfc8f5f6 --- /dev/null +++ b/lib/gitlab/template/base_template.rb @@ -0,0 +1,54 @@ +module Gitlab + module Template + class BaseTemplate + def initialize(path) + @path = path + end + + def name + File.basename(@path, self.class.extension) + end + + def content + File.read(@path) + end + + class << self + def all + self.category_directories.flat_map do |dir| + templates_for_folder(dir) + end + end + + def find(key) + file_name = "#{key}#{self.extension}" + + directory = select_directory(file_name) + directory ? new(File.join(directory, file_name)) : nil + end + + def by_category(category) + templates_for_folder(categories[category]) + end + + def category_directories + self.categories.values.map { |subdir| File.join(base_dir, subdir)} + end + + private + + def select_directory(file_name) + category_directories.find { |dir| File.exist?(File.join(dir, file_name)) } + end + + def templates_for_folder(dir) + Dir.glob("#{dir.to_s}/*#{self.extension}").select { |f| f =~ filter_regex }.map { |f| new(f) } + end + + def filter_regex + /#{Regexp.escape(extension)}\z/ + end + end + end + end +end diff --git a/lib/gitlab/template/gitignore.rb b/lib/gitlab/template/gitignore.rb new file mode 100644 index 00000000000..73fb3b18c4d --- /dev/null +++ b/lib/gitlab/template/gitignore.rb @@ -0,0 +1,23 @@ +module Gitlab + module Template + class Gitignore < BaseTemplate + + class << self + def extension + '.gitignore' + end + + def categories + { + Languages: '', + Global: 'Global' + } + end + + def base_dir + Rails.root.join('vendor/gitignore') + end + end + end + end +end diff --git a/lib/tasks/gitlab/update_gitignore.rake b/lib/tasks/gitlab/update_gitignore.rake deleted file mode 100644 index 4fd48cccb1d..00000000000 --- a/lib/tasks/gitlab/update_gitignore.rake +++ /dev/null @@ -1,46 +0,0 @@ -namespace :gitlab do - desc "GitLab | Update gitignore" - task :update_gitignore do - unless clone_gitignores - puts "Cloning the gitignores failed".color(:red) - return - end - - remove_unneeded_files(gitignore_directory) - remove_unneeded_files(global_directory) - - puts "Done".color(:green) - end - - def clone_gitignores - FileUtils.rm_rf(gitignore_directory) if Dir.exist?(gitignore_directory) - FileUtils.cd vendor_directory - - system('git clone --depth=1 --branch=master https://github.com/github/gitignore.git') - end - - # Retain only certain files: - # - The LICENSE, because we have to - # - The sub dir global - # - The gitignores themself - # - Dir.entires returns also the entries '.' and '..' - def remove_unneeded_files(path) - Dir.foreach(path) do |file| - FileUtils.rm_rf(File.join(path, file)) unless file =~ /(\.{1,2}|LICENSE|Global|\.gitignore)\z/ - end - end - - private - - def vendor_directory - Rails.root.join('vendor') - end - - def gitignore_directory - File.join(vendor_directory, 'gitignore') - end - - def global_directory - File.join(gitignore_directory, 'Global') - end -end diff --git a/lib/tasks/gitlab/update_templates.rake b/lib/tasks/gitlab/update_templates.rake new file mode 100644 index 00000000000..36ffad8aae9 --- /dev/null +++ b/lib/tasks/gitlab/update_templates.rake @@ -0,0 +1,61 @@ +namespace :gitlab do + desc "GitLab | Update templates" + task :update_templates do + update("gitignore") + update("gitlab-ci-yml") + end + + def update(directory) + unless clone_repository(directory) + puts "Cloning the #{directory} templates failed".red + return + end + + remove_unneeded_files(directory) + 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 + + system("git clone --depth=1 --branch=master #{TEMPLATE_DATA[directory]}") + end + + # Retain only certain files: + # - The LICENSE, because we have to + # - The sub dir global + # - The gitignores themself + # - Dir.entires returns also the entries '.' and '..' + def remove_unneeded_files(directory) + regex = CLEANUP_REGEX[directory] + Dir.foreach(directory) do |file| + FileUtils.rm_rf(File.join(directory, file)) unless file =~ regex + end + end + + 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 + + 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/lib/gitlab/gitignore_spec.rb b/spec/lib/gitlab/gitignore_spec.rb deleted file mode 100644 index 72baa516cc4..00000000000 --- a/spec/lib/gitlab/gitignore_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Gitignore do - subject { Gitlab::Gitignore } - - describe '.all' do - it 'strips the gitignore suffix' do - expect(subject.all.first.name).not_to end_with('.gitignore') - end - - it 'combines the globals and rest' do - all = subject.all.map(&:name) - - expect(all).to include('Vim') - expect(all).to include('Ruby') - end - end - - describe '.find' do - it 'returns nil if the file does not exist' do - expect(subject.find('mepmep-yadida')).to be nil - end - - it 'returns the Gitignore object of a valid file' do - ruby = subject.find('Ruby') - - expect(ruby).to be_a Gitlab::Gitignore - expect(ruby.name).to eq('Ruby') - end - end - - describe '#content' do - it 'loads the full file' do - gitignore = subject.new(Rails.root.join('vendor/gitignore/Ruby.gitignore')) - - expect(gitignore.name).to eq 'Ruby' - expect(gitignore.content).to start_with('*.gem') - end - end -end diff --git a/spec/lib/gitlab/template/gitignore_spec.rb b/spec/lib/gitlab/template/gitignore_spec.rb new file mode 100644 index 00000000000..bc0ec9325cc --- /dev/null +++ b/spec/lib/gitlab/template/gitignore_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe Gitlab::Template::Gitignore do + subject { described_class } + + describe '.all' do + it 'strips the gitignore suffix' do + expect(subject.all.first.name).not_to end_with('.gitignore') + end + + it 'combines the globals and rest' do + all = subject.all.map(&:name) + + expect(all).to include('Vim') + expect(all).to include('Ruby') + end + end + + describe '.find' do + it 'returns nil if the file does not exist' do + expect(subject.find('mepmep-yadida')).to be nil + end + + it 'returns the Gitignore object of a valid file' do + ruby = subject.find('Ruby') + + expect(ruby).to be_a Gitlab::Template::Gitignore + expect(ruby.name).to eq('Ruby') + end + end + + describe '#content' do + it 'loads the full file' do + gitignore = subject.new(Rails.root.join('vendor/gitignore/Ruby.gitignore')) + + expect(gitignore.name).to eq 'Ruby' + expect(gitignore.content).to start_with('*.gem') + end + end +end diff --git a/spec/requests/api/gitignores_spec.rb b/spec/requests/api/gitignores_spec.rb index aab2d8c81b9..9130312c057 100644 --- a/spec/requests/api/gitignores_spec.rb +++ b/spec/requests/api/gitignores_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe API::Gitignores, api: true do +describe API::Templates, api: true do include ApiHelpers describe 'Entity Gitignore' do -- cgit v1.2.3