Merge branch '22818-licence-gitignore-and-yml-endpoints-removal' into 'master'

Remove deprecated templates endpoints in V4

Closes #22818

See merge request !8853
This commit is contained in:
Rémy Coutable 2017-02-13 18:44:14 +00:00
commit 49e44d88b9
8 changed files with 398 additions and 97 deletions

View File

@ -11,7 +11,7 @@
licensePath: "/api/:version/templates/licenses/:key",
gitignorePath: "/api/:version/templates/gitignores/:key",
gitlabCiYmlPath: "/api/:version/templates/gitlab_ci_ymls/:key",
dockerfilePath: "/api/:version/dockerfiles/:key",
dockerfilePath: "/api/:version/templates/dockerfiles/:key",
issuableTemplatePath: "/:namespace_path/:project_path/templates/:type/:key",
group: function(group_id, callback) {
var url = Api.buildUrl(Api.groupPath)

View File

@ -0,0 +1,4 @@
---
title: V3 deprecated templates endpoints removal
merge_request: 8853
author:

View File

@ -13,3 +13,13 @@ changes are in V4:
- Project snippets do not return deprecated field `expires_at`
- Endpoints under `projects/:id/keys` have been removed (use `projects/:id/deploy_keys`)
- Status 409 returned for POST `project/:id/members` when a member already exists
- Removed the following deprecated Templates endpoints (these are still accessible with `/templates` prefix)
- `/licences`
- `/licences/:key`
- `/gitignores`
- `/gitlab_ci_ymls`
- `/dockerfiles`
- `/gitignores/:key`
- `/gitlab_ci_ymls/:key`
- `/dockerfiles/:key`

View File

@ -11,6 +11,7 @@ module API
mount ::API::V3::MergeRequests
mount ::API::V3::Projects
mount ::API::V3::ProjectSnippets
mount ::API::V3::Templates
end
before { allow_access_with_scope :api }

View File

@ -24,7 +24,6 @@ module API
/[\<\{\[]
(fullname|name\sof\s(author|copyright\sowner))
[\>\}\]]/xi.freeze
DEPRECATION_MESSAGE = ' This endpoint is deprecated and will be removed in GitLab 9.0.'.freeze
helpers do
def parsed_license_template
@ -46,74 +45,58 @@ module API
end
end
{ "licenses" => :deprecated, "templates/licenses" => :ok }.each do |route, status|
desc 'Get the list of the available license template' do
detailed_desc = 'This feature was introduced in GitLab 8.7.'
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success Entities::RepoLicense
end
params do
optional :popular, type: Boolean, desc: 'If passed, returns only popular licenses'
end
get route do
options = {
featured: declared(params).popular.present? ? true : nil
}
present Licensee::License.all(options), with: Entities::RepoLicense
end
desc 'Get the list of the available license template' do
detail 'This feature was introduced in GitLab 8.7.'
success ::API::Entities::RepoLicense
end
params do
optional :popular, type: Boolean, desc: 'If passed, returns only popular licenses'
end
get "templates/licenses" do
options = {
featured: declared(params).popular.present? ? true : nil
}
present Licensee::License.all(options), with: ::API::Entities::RepoLicense
end
{ "licenses/:name" => :deprecated, "templates/licenses/:name" => :ok }.each do |route, status|
desc 'Get the text for a specific license' do
detailed_desc = 'This feature was introduced in GitLab 8.7.'
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success Entities::RepoLicense
end
params do
requires :name, type: String, desc: 'The name of the template'
end
get route, requirements: { name: /[\w\.-]+/ } do
not_found!('License') unless Licensee::License.find(declared(params).name)
desc 'Get the text for a specific license' do
detail 'This feature was introduced in GitLab 8.7.'
success ::API::Entities::RepoLicense
end
params do
requires :name, type: String, desc: 'The name of the template'
end
get "templates/licenses/:name", requirements: { name: /[\w\.-]+/ } do
not_found!('License') unless Licensee::License.find(declared(params).name)
template = parsed_license_template
template = parsed_license_template
present template, with: Entities::RepoLicense
end
present template, with: ::API::Entities::RepoLicense
end
GLOBAL_TEMPLATE_TYPES.each do |template_type, properties|
klass = properties[:klass]
gitlab_version = properties[:gitlab_version]
{ template_type => :deprecated, "templates/#{template_type}" => :ok }.each do |route, status|
desc 'Get the list of the available template' do
detailed_desc = "This feature was introduced in GitLab #{gitlab_version}."
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success Entities::TemplatesList
end
get route do
present klass.all, with: Entities::TemplatesList
end
desc 'Get the list of the available template' do
detail "This feature was introduced in GitLab #{gitlab_version}."
success Entities::TemplatesList
end
get "templates/#{template_type}" do
present klass.all, with: Entities::TemplatesList
end
{ "#{template_type}/:name" => :deprecated, "templates/#{template_type}/:name" => :ok }.each do |route, status|
desc 'Get the text for a specific template present in local filesystem' do
detailed_desc = "This feature was introduced in GitLab #{gitlab_version}."
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success Entities::Template
end
params do
requires :name, type: String, desc: 'The name of the template'
end
get route do
new_template = klass.find(declared(params).name)
desc 'Get the text for a specific template present in local filesystem' do
detail "This feature was introduced in GitLab #{gitlab_version}."
success Entities::Template
end
params do
requires :name, type: String, desc: 'The name of the template'
end
get "templates/#{template_type}/:name" do
new_template = klass.find(declared(params).name)
render_response(template_type, new_template)
end
render_response(template_type, new_template)
end
end
end

122
lib/api/v3/templates.rb Normal file
View File

@ -0,0 +1,122 @@
module API
module V3
class Templates < Grape::API
GLOBAL_TEMPLATE_TYPES = {
gitignores: {
klass: Gitlab::Template::GitignoreTemplate,
gitlab_version: 8.8
},
gitlab_ci_ymls: {
klass: Gitlab::Template::GitlabCiYmlTemplate,
gitlab_version: 8.9
},
dockerfiles: {
klass: Gitlab::Template::DockerfileTemplate,
gitlab_version: 8.15
}
}.freeze
PROJECT_TEMPLATE_REGEX =
/[\<\{\[]
(project|description|
one\sline\s.+\swhat\sit\sdoes\.) # matching the start and end is enough here
[\>\}\]]/xi.freeze
YEAR_TEMPLATE_REGEX = /[<{\[](year|yyyy)[>}\]]/i.freeze
FULLNAME_TEMPLATE_REGEX =
/[\<\{\[]
(fullname|name\sof\s(author|copyright\sowner))
[\>\}\]]/xi.freeze
DEPRECATION_MESSAGE = ' This endpoint is deprecated and has been removed in V4.'.freeze
helpers do
def parsed_license_template
# We create a fresh Licensee::License object since we'll modify its
# content in place below.
template = Licensee::License.new(params[:name])
template.content.gsub!(YEAR_TEMPLATE_REGEX, Time.now.year.to_s)
template.content.gsub!(PROJECT_TEMPLATE_REGEX, params[:project]) if params[:project].present?
fullname = params[:fullname].presence || current_user.try(:name)
template.content.gsub!(FULLNAME_TEMPLATE_REGEX, fullname) if fullname
template
end
def render_response(template_type, template)
not_found!(template_type.to_s.singularize) unless template
present template, with: ::API::Entities::Template
end
end
{ "licenses" => :deprecated, "templates/licenses" => :ok }.each do |route, status|
desc 'Get the list of the available license template' do
detailed_desc = 'This feature was introduced in GitLab 8.7.'
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success ::API::Entities::RepoLicense
end
params do
optional :popular, type: Boolean, desc: 'If passed, returns only popular licenses'
end
get route do
options = {
featured: declared(params).popular.present? ? true : nil
}
present Licensee::License.all(options), with: ::API::Entities::RepoLicense
end
end
{ "licenses/:name" => :deprecated, "templates/licenses/:name" => :ok }.each do |route, status|
desc 'Get the text for a specific license' do
detailed_desc = 'This feature was introduced in GitLab 8.7.'
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success ::API::Entities::RepoLicense
end
params do
requires :name, type: String, desc: 'The name of the template'
end
get route, requirements: { name: /[\w\.-]+/ } do
not_found!('License') unless Licensee::License.find(declared(params).name)
template = parsed_license_template
present template, with: ::API::Entities::RepoLicense
end
end
GLOBAL_TEMPLATE_TYPES.each do |template_type, properties|
klass = properties[:klass]
gitlab_version = properties[:gitlab_version]
{ template_type => :deprecated, "templates/#{template_type}" => :ok }.each do |route, status|
desc 'Get the list of the available template' do
detailed_desc = "This feature was introduced in GitLab #{gitlab_version}."
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success ::API::Entities::TemplatesList
end
get route do
present klass.all, with: ::API::Entities::TemplatesList
end
end
{ "#{template_type}/:name" => :deprecated, "templates/#{template_type}/:name" => :ok }.each do |route, status|
desc 'Get the text for a specific template present in local filesystem' do
detailed_desc = "This feature was introduced in GitLab #{gitlab_version}."
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success ::API::Entities::Template
end
params do
requires :name, type: String, desc: 'The name of the template'
end
get route do
new_template = klass.find(declared(params).name)
render_response(template_type, new_template)
end
end
end
end
end
end

View File

@ -3,23 +3,23 @@ require 'spec_helper'
describe API::Templates, api: true do
include ApiHelpers
shared_examples_for 'the Template Entity' do |path|
before { get api(path) }
context 'the Template Entity' do
before { get api('/templates/gitignores/Ruby') }
it { expect(json_response['name']).to eq('Ruby') }
it { expect(json_response['content']).to include('*.gem') }
end
shared_examples_for 'the TemplateList Entity' do |path|
before { get api(path) }
context 'the TemplateList Entity' do
before { get api('/templates/gitignores') }
it { expect(json_response.first['name']).not_to be_nil }
it { expect(json_response.first['content']).to be_nil }
end
shared_examples_for 'requesting gitignores' do |path|
context 'requesting gitignores' do
it 'returns a list of available gitignore templates' do
get api(path)
get api('/templates/gitignores')
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
@ -27,9 +27,9 @@ describe API::Templates, api: true do
end
end
shared_examples_for 'requesting gitlab-ci-ymls' do |path|
context 'requesting gitlab-ci-ymls' do
it 'returns a list of available gitlab_ci_ymls' do
get api(path)
get api('/templates/gitlab_ci_ymls')
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
@ -37,17 +37,17 @@ describe API::Templates, api: true do
end
end
shared_examples_for 'requesting gitlab-ci-yml for Ruby' do |path|
context 'requesting gitlab-ci-yml for Ruby' do
it 'adds a disclaimer on the top' do
get api(path)
get api('/templates/gitlab_ci_ymls/Ruby')
expect(response).to have_http_status(200)
expect(json_response['content']).to start_with("# This file is a template,")
end
end
shared_examples_for 'the License Template Entity' do |path|
before { get api(path) }
context 'the License Template Entity' do
before { get api('/templates/licenses/mit') }
it 'returns a license template' do
expect(json_response['key']).to eq('mit')
@ -64,9 +64,9 @@ describe API::Templates, api: true do
end
end
shared_examples_for 'GET licenses' do |path|
context 'GET templates/licenses' do
it 'returns a list of available license templates' do
get api(path)
get api('/templates/licenses')
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
@ -77,7 +77,7 @@ describe API::Templates, api: true do
describe 'the popular parameter' do
context 'with popular=1' do
it 'returns a list of available popular license templates' do
get api("#{path}?popular=1")
get api('/templates/licenses?popular=1')
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
@ -88,10 +88,10 @@ describe API::Templates, api: true do
end
end
shared_examples_for 'GET licenses/:name' do |path|
context 'GET templates/licenses/:name' do
context 'with :project and :fullname given' do
before do
get api("#{path}/#{license_type}?project=My+Awesome+Project&fullname=Anton+#{license_type.upcase}")
get api("/templates/licenses/#{license_type}?project=My+Awesome+Project&fullname=Anton+#{license_type.upcase}")
end
context 'for the mit license' do
@ -178,26 +178,4 @@ describe API::Templates, api: true do
end
end
end
describe 'with /templates namespace' do
it_behaves_like 'the Template Entity', '/templates/gitignores/Ruby'
it_behaves_like 'the TemplateList Entity', '/templates/gitignores'
it_behaves_like 'requesting gitignores', '/templates/gitignores'
it_behaves_like 'requesting gitlab-ci-ymls', '/templates/gitlab_ci_ymls'
it_behaves_like 'requesting gitlab-ci-yml for Ruby', '/templates/gitlab_ci_ymls/Ruby'
it_behaves_like 'the License Template Entity', '/templates/licenses/mit'
it_behaves_like 'GET licenses', '/templates/licenses'
it_behaves_like 'GET licenses/:name', '/templates/licenses'
end
describe 'without /templates namespace' do
it_behaves_like 'the Template Entity', '/gitignores/Ruby'
it_behaves_like 'the TemplateList Entity', '/gitignores'
it_behaves_like 'requesting gitignores', '/gitignores'
it_behaves_like 'requesting gitlab-ci-ymls', '/gitlab_ci_ymls'
it_behaves_like 'requesting gitlab-ci-yml for Ruby', '/gitlab_ci_ymls/Ruby'
it_behaves_like 'the License Template Entity', '/licenses/mit'
it_behaves_like 'GET licenses', '/licenses'
it_behaves_like 'GET licenses/:name', '/licenses'
end
end

View File

@ -0,0 +1,203 @@
require 'spec_helper'
describe API::V3::Templates, api: true do
include ApiHelpers
shared_examples_for 'the Template Entity' do |path|
before { get v3_api(path) }
it { expect(json_response['name']).to eq('Ruby') }
it { expect(json_response['content']).to include('*.gem') }
end
shared_examples_for 'the TemplateList Entity' do |path|
before { get v3_api(path) }
it { expect(json_response.first['name']).not_to be_nil }
it { expect(json_response.first['content']).to be_nil }
end
shared_examples_for 'requesting gitignores' do |path|
it 'returns a list of available gitignore templates' do
get v3_api(path)
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to be > 15
end
end
shared_examples_for 'requesting gitlab-ci-ymls' do |path|
it 'returns a list of available gitlab_ci_ymls' do
get v3_api(path)
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).not_to be_nil
end
end
shared_examples_for 'requesting gitlab-ci-yml for Ruby' do |path|
it 'adds a disclaimer on the top' do
get v3_api(path)
expect(response).to have_http_status(200)
expect(json_response['content']).to start_with("# This file is a template,")
end
end
shared_examples_for 'the License Template Entity' do |path|
before { get v3_api(path) }
it 'returns a license template' do
expect(json_response['key']).to eq('mit')
expect(json_response['name']).to eq('MIT License')
expect(json_response['nickname']).to be_nil
expect(json_response['popular']).to be true
expect(json_response['html_url']).to eq('http://choosealicense.com/licenses/mit/')
expect(json_response['source_url']).to eq('https://opensource.org/licenses/MIT')
expect(json_response['description']).to include('A permissive license that is short and to the point.')
expect(json_response['conditions']).to eq(%w[include-copyright])
expect(json_response['permissions']).to eq(%w[commercial-use modifications distribution private-use])
expect(json_response['limitations']).to eq(%w[no-liability])
expect(json_response['content']).to include('The MIT License (MIT)')
end
end
shared_examples_for 'GET licenses' do |path|
it 'returns a list of available license templates' do
get v3_api(path)
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(15)
expect(json_response.map { |l| l['key'] }).to include('agpl-3.0')
end
describe 'the popular parameter' do
context 'with popular=1' do
it 'returns a list of available popular license templates' do
get v3_api("#{path}?popular=1")
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(3)
expect(json_response.map { |l| l['key'] }).to include('apache-2.0')
end
end
end
end
shared_examples_for 'GET licenses/:name' do |path|
context 'with :project and :fullname given' do
before do
get v3_api("#{path}/#{license_type}?project=My+Awesome+Project&fullname=Anton+#{license_type.upcase}")
end
context 'for the mit license' do
let(:license_type) { 'mit' }
it 'returns the license text' do
expect(json_response['content']).to include('The MIT License (MIT)')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include("Copyright (c) #{Time.now.year} Anton")
end
end
context 'for the agpl-3.0 license' do
let(:license_type) { 'agpl-3.0' }
it 'returns the license text' do
expect(json_response['content']).to include('GNU AFFERO GENERAL PUBLIC LICENSE')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include('My Awesome Project')
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
end
end
context 'for the gpl-3.0 license' do
let(:license_type) { 'gpl-3.0' }
it 'returns the license text' do
expect(json_response['content']).to include('GNU GENERAL PUBLIC LICENSE')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include('My Awesome Project')
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
end
end
context 'for the gpl-2.0 license' do
let(:license_type) { 'gpl-2.0' }
it 'returns the license text' do
expect(json_response['content']).to include('GNU GENERAL PUBLIC LICENSE')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include('My Awesome Project')
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
end
end
context 'for the apache-2.0 license' do
let(:license_type) { 'apache-2.0' }
it 'returns the license text' do
expect(json_response['content']).to include('Apache License')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include("Copyright #{Time.now.year} Anton")
end
end
context 'for an uknown license' do
let(:license_type) { 'muth-over9000' }
it 'returns a 404' do
expect(response).to have_http_status(404)
end
end
end
context 'with no :fullname given' do
context 'with an authenticated user' do
let(:user) { create(:user) }
it 'replaces the copyright owner placeholder with the name of the current user' do
get v3_api('/templates/licenses/mit', user)
expect(json_response['content']).to include("Copyright (c) #{Time.now.year} #{user.name}")
end
end
end
end
describe 'with /templates namespace' do
it_behaves_like 'the Template Entity', '/templates/gitignores/Ruby'
it_behaves_like 'the TemplateList Entity', '/templates/gitignores'
it_behaves_like 'requesting gitignores', '/templates/gitignores'
it_behaves_like 'requesting gitlab-ci-ymls', '/templates/gitlab_ci_ymls'
it_behaves_like 'requesting gitlab-ci-yml for Ruby', '/templates/gitlab_ci_ymls/Ruby'
it_behaves_like 'the License Template Entity', '/templates/licenses/mit'
it_behaves_like 'GET licenses', '/templates/licenses'
it_behaves_like 'GET licenses/:name', '/templates/licenses'
end
describe 'without /templates namespace' do
it_behaves_like 'the Template Entity', '/gitignores/Ruby'
it_behaves_like 'the TemplateList Entity', '/gitignores'
it_behaves_like 'requesting gitignores', '/gitignores'
it_behaves_like 'requesting gitlab-ci-ymls', '/gitlab_ci_ymls'
it_behaves_like 'requesting gitlab-ci-yml for Ruby', '/gitlab_ci_ymls/Ruby'
it_behaves_like 'the License Template Entity', '/licenses/mit'
it_behaves_like 'GET licenses', '/licenses'
it_behaves_like 'GET licenses/:name', '/licenses'
end
end