summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/helpers/blob_helper.rb4
-rw-r--r--app/models/repository.rb20
-rw-r--r--app/views/projects/blob/_editor.html.haml3
-rw-r--r--app/views/projects/empty.html.haml10
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/entities.rb8
-rw-r--r--lib/api/gitignores.rb29
-rw-r--r--lib/gitlab/gitignore.rb68
-rw-r--r--lib/tasks/gitlab/update_gitignore.rake26
-rw-r--r--spec/lib/gitlab/gitignore_spec.rb38
-rw-r--r--spec/requests/api/gitignores_spec.rb29
11 files changed, 227 insertions, 9 deletions
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 93241b3afb7..fb1b7649465 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -184,4 +184,8 @@ module BlobHelper
Other: licenses.reject(&:featured).map { |license| [license.name, license.key] }
}
end
+
+ def gitignores_for_select
+ @gitignores_for_select ||= Gitlab::Gitignore.all
+ end
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 47a7223c723..f26278cc3af 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -472,9 +472,7 @@ class Repository
def changelog
cache.fetch(:changelog) do
- tree(:head).blobs.find do |file|
- file.name =~ /\A(changelog|history|changes|news)/i
- end
+ file_on_head(/\A(changelog|history|changes|news)/i)
end
end
@@ -482,9 +480,7 @@ class Repository
return nil unless head_exists?
cache.fetch(:license_blob) do
- tree(:head).blobs.find do |file|
- file.name =~ /\A(licen[sc]e|copying)(\..+|\z)/i
- end
+ file_on_head(/\A(licen[sc]e|copying)(\..+|\z)/i)
end
end
@@ -496,6 +492,14 @@ class Repository
end
end
+ def gitignore
+ return nil if !exists? || empty?
+
+ cache.fetch(:gitignore) do
+ file_on_head(/\A\.gitignore\z/)
+ end
+ end
+
def gitlab_ci_yml
return nil unless head_exists?
@@ -989,4 +993,8 @@ class Repository
def head_exists?
exists? && !empty? && !rugged.head_unborn?
end
+
+ def file_on_head(regex)
+ tree(:head).blobs.find { |file| file.name =~ regex }
+ end
end
diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml
index fefa652a3da..eac5014b7c9 100644
--- a/app/views/projects/blob/_editor.html.haml
+++ b/app/views/projects/blob/_editor.html.haml
@@ -16,6 +16,9 @@
.license-selector.js-license-selector.hide
= select_tag :license_type, grouped_options_for_select(licenses_for_select, @project.repository.license_key), include_blank: true, class: 'select2 license-select', data: {placeholder: 'Choose a license template', project: @project.name, fullname: @project.namespace.human_name}
+ .gitignore-selector.js-gitignore-selector.hide
+ = select_tag :gitignore_template, options_for_select(Gitlab::Gitignore.all), include_blank: true, class: 'select2 gitignore-select', data: {placeholder: 'Choose a .gitignore template'}
+
.encoding-selector
= select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'select2'
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index 1a2e59752fe..636beb73ec2 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -15,10 +15,14 @@
If you already have files you can push them using command line instructions below.
%p
Otherwise you can start with adding a
- = link_to "README", new_readme_path, class: 'underlined-link'
+ = succeed ',' do
+ = link_to "README", new_readme_path, class: 'underlined-link'
+ a
+ = succeed ',' do
+ = link_to "LICENSE", add_special_file_path(@project, file_name: 'LICENSE'), class: 'underlined-link'
or a
- = link_to "LICENSE", add_special_file_path(@project, file_name: 'LICENSE'), class: 'underlined-link'
- file to this project.
+ = link_to '.gitignore', add_special_file_path(@project, file_name: '.gitignore'), class: 'underlined-link'
+ to this project.
- if can?(current_user, :push_code, @project)
%div{ class: container_class }
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 360fb41a721..6cd909f6115 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -58,5 +58,6 @@ module API
mount ::API::Runners
mount ::API::Licenses
mount ::API::Subscriptions
+ mount ::API::Gitignores
end
end
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 8298e3ad34c..31491cf31dd 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -457,5 +457,13 @@ module API
expose(:limitations) { |license| license.meta['limitations'] }
expose :content
end
+
+ class GitignoresList < Grape::Entity
+ expose :name
+ end
+
+ class Gitignore < Grape::Entity
+ expose :name, :content
+ end
end
end
diff --git a/lib/api/gitignores.rb b/lib/api/gitignores.rb
new file mode 100644
index 00000000000..1af9ba6b316
--- /dev/null
+++ b/lib/api/gitignores.rb
@@ -0,0 +1,29 @@
+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:
+ # key (required) - The key of a license
+ #
+ # Example Request:
+ # GET /gitignores/elixir
+ #
+ get 'gitignores/:key' do
+ required_attributes! [:key]
+
+ gitignore = Gitlab::Gitignore.find(params[:key])
+ not_found!('.gitignore') unless gitignore
+
+ present gitignore, with: Entities::Gitignore
+ end
+ end
+end
diff --git a/lib/gitlab/gitignore.rb b/lib/gitlab/gitignore.rb
new file mode 100644
index 00000000000..a2de2831e38
--- /dev/null
+++ b/lib/gitlab/gitignore.rb
@@ -0,0 +1,68 @@
+module Gitlab
+ class Gitignore
+ FILTER_REGEX = /\.gitignore\z/.freeze
+
+ attr_accessor :name, :directory
+
+ def initialize(name, directory)
+ @name = name
+ @directory = directory
+ 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(key, directory) : nil
+ end
+
+ def global
+ files_for_folder(global_dir).map { |f| new(f, global_dir) }
+ end
+
+ def languages_frameworks
+ files_for_folder(gitignore_dir).map { |f| new(f, gitignore_dir) }
+ end
+ end
+
+ private
+
+ def path
+ File.expand_path("#{name}.gitignore", directory)
+ end
+
+ class << self
+ def select_directory(file_name)
+ [self.gitignore_dir, self.global_dir].find { |dir| File.exist?(File.expand_path(file_name, dir)) }
+ end
+
+ def global_dir
+ File.expand_path('Global', gitignore_dir)
+ end
+
+ def gitignore_dir
+ File.expand_path('vendor/gitignore', Rails.root)
+ end
+
+ def files_for_folder(dir)
+ gitignores = []
+ Dir.entries(dir).each do |e|
+ next unless e.end_with?('.gitignore')
+
+ gitignores << e.gsub(FILTER_REGEX, '')
+ end
+
+ gitignores
+ end
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/update_gitignore.rake b/lib/tasks/gitlab/update_gitignore.rake
new file mode 100644
index 00000000000..61cbfd6737d
--- /dev/null
+++ b/lib/tasks/gitlab/update_gitignore.rake
@@ -0,0 +1,26 @@
+namespace :gitlab do
+ desc "GitLab | Update gitignore"
+ task :update_gitignore do
+ dir = File.expand_path('vendor', Rails.root)
+ FileUtils.cd(dir)
+
+ dir = File.expand_path('gitignore', dir)
+ clone_gitignores(dir)
+ remove_unneeded_files(dir)
+
+ puts "Done".green
+ end
+
+ def clone_gitignores(dir)
+ FileUtils.rm_rf(dir) if Dir.exist?(dir)
+ system('git clone --depth=1 --branch=master https://github.com/github/gitignore.git')
+ end
+
+ def remove_unneeded_files(dir)
+ [File.expand_path('Global', dir), dir].each do |path|
+ Dir.entries(path).reject { |e| e =~ /(\.{1,2}|Global|\.gitignore)\z/ }.each do |file|
+ FileUtils.rm_rf File.expand_path(file, path)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/gitignore_spec.rb b/spec/lib/gitlab/gitignore_spec.rb
new file mode 100644
index 00000000000..5dab821a8ec
--- /dev/null
+++ b/spec/lib/gitlab/gitignore_spec.rb
@@ -0,0 +1,38 @@
+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
+ end
+ end
+
+ describe '#content' do
+ it 'loads the full file' do
+ gitignore = subject.new('Ruby', File.expand_path('vendor/gitignore', Rails.root))
+
+ 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
new file mode 100644
index 00000000000..d0e576e637c
--- /dev/null
+++ b/spec/requests/api/gitignores_spec.rb
@@ -0,0 +1,29 @@
+require 'spec_helper'
+
+describe API::Gitignores, 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']).to be_truthy }
+ it { expect(json_response.first['content']).to be_falsey }
+ 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