From 25004cbc32432d989a05532925c5c4c591cca1b5 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Fri, 3 Jun 2016 11:44:04 +0200 Subject: [PATCH 1/8] Snippets get award emoji! :thumbsup: --- CHANGELOG | 1 + .../concerns/toggle_award_emoji.rb | 8 +++-- app/controllers/snippets_controller.rb | 3 ++ app/models/snippet.rb | 1 + config/routes.rb | 3 +- lib/api/award_emoji.rb | 2 +- spec/controllers/snippets_controller_spec.rb | 31 +++++++++++++++++-- spec/models/snippet_spec.rb | 2 ++ spec/requests/api/award_emoji_spec.rb | 7 +++++ 9 files changed, 52 insertions(+), 6 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d133909748b..786e9113af2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -508,6 +508,7 @@ v 8.10.0 - Updated project header design - Issuable collapsed assignee tooltip is now the users name - Fix compare view not changing code view rendering style + - Emoji can be awarded on Snippets !4456 - Exclude email check from the standard health check - Updated layout for Projects, Groups, Users on Admin area. !4424 - Fix changing issue state columns in milestone view diff --git a/app/controllers/concerns/toggle_award_emoji.rb b/app/controllers/concerns/toggle_award_emoji.rb index 172d5344b7a..13086da7d5e 100644 --- a/app/controllers/concerns/toggle_award_emoji.rb +++ b/app/controllers/concerns/toggle_award_emoji.rb @@ -10,7 +10,9 @@ module ToggleAwardEmoji if awardable.user_can_award?(current_user, name) awardable.toggle_award_emoji(name, current_user) - TodoService.new.new_award_emoji(to_todoable(awardable), current_user) + + todoable = to_todoable(awardable) + TodoService.new.new_award_emoji(todoable, current_user) if todoable render json: { ok: true } else @@ -24,8 +26,10 @@ module ToggleAwardEmoji case awardable when Note awardable.noteable - else + when MergeRequest, Issue awardable + when Snippet + nil end end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 2a17c1f34db..d198782138a 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -1,4 +1,6 @@ class SnippetsController < ApplicationController + include ToggleAwardEmoji + before_action :snippet, only: [:show, :edit, :destroy, :update, :raw] # Allow read snippet @@ -85,6 +87,7 @@ class SnippetsController < ApplicationController PersonalSnippet.find(params[:id]) end end + alias_method :awardable, :snippet def authorize_read_snippet! authenticate_user! unless can?(current_user, :read_personal_snippet, @snippet) diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 5ec933601ac..8a1730f3f36 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -4,6 +4,7 @@ class Snippet < ActiveRecord::Base include Participable include Referable include Sortable + include Awardable default_value_for :visibility_level, Snippet::PRIVATE diff --git a/config/routes.rb b/config/routes.rb index 068c92d1400..637e5c1bac4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -101,6 +101,7 @@ Rails.application.routes.draw do resources :snippets do member do get 'raw' + post :toggle_award_emoji end end @@ -110,7 +111,6 @@ Rails.application.routes.draw do # # Invites # - resources :invites, only: [:show], constraints: { id: /[A-Za-z0-9_-]+/ } do member do post :accept @@ -665,6 +665,7 @@ Rails.application.routes.draw do resources :snippets, constraints: { id: /\d+/ } do member do get 'raw' + post :toggle_award_emoji end end diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index 7c22b17e4e5..2898e8222fa 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -1,7 +1,7 @@ module API class AwardEmoji < Grape::API before { authenticate! } - AWARDABLES = [Issue, MergeRequest] + AWARDABLES = [Issue, MergeRequest, Snippet] resource :projects do AWARDABLES.each do |awardable_type| diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb index 2a89159c070..2ea57e50e76 100644 --- a/spec/controllers/snippets_controller_spec.rb +++ b/spec/controllers/snippets_controller_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' describe SnippetsController do - describe 'GET #show' do - let(:user) { create(:user) } + let(:user) { create(:user) } + describe 'GET #show' do context 'when the personal snippet is private' do let(:personal_snippet) { create(:personal_snippet, :private, author: user) } @@ -230,4 +230,31 @@ describe SnippetsController do end end end + + context 'award emoji on snippets' do + let(:personal_snippet) { create(:personal_snippet, :private, author: user) } + + before do + sign_in(user) + end + + describe 'POST #toggle_award_emoji' do + it "toggles the award emoji" do + expect do + post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") + end.to change { personal_snippet.award_emoji.count }.by(1) + + expect(response.status).to eq(200) + end + + it "removes the already awarded emoji" do + post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") + expect do + post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") + end.to change { personal_snippet.award_emoji.count }.by(-1) + + expect(response.status).to eq(200) + end + end + end end diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index 0621c6a06ce..e6bc5296398 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -9,12 +9,14 @@ describe Snippet, models: true do it { is_expected.to include_module(Participable) } it { is_expected.to include_module(Referable) } it { is_expected.to include_module(Sortable) } + it { is_expected.to include_module(Awardable) } end describe 'associations' do it { is_expected.to belong_to(:author).class_name('User') } it { is_expected.to belong_to(:project) } it { is_expected.to have_many(:notes).dependent(:destroy) } + it { is_expected.to have_many(:award_emoji).dependent(:destroy) } end describe 'validation' do diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb index 981a6791881..f55702794f6 100644 --- a/spec/requests/api/award_emoji_spec.rb +++ b/spec/requests/api/award_emoji_spec.rb @@ -14,6 +14,9 @@ describe API::API, api: true do describe "GET /projects/:id/awardable/:awardable_id/award_emoji" do context 'on an issue' do + let(:issue) { create(:issue, project: project, author: user) } + let!(:award_emoji) { create(:award_emoji, awardable: issue, user: user) } + it "returns an array of award_emoji" do get api("/projects/#{project.id}/issues/#{issue.id}/award_emoji", user) @@ -39,6 +42,10 @@ describe API::API, api: true do end end + context 'on a snippet' do + it 'returns the awarded ' + end + context 'when the user has no access' do it 'returns a status code 404' do user1 = create(:user) From 7475f9d175482254b9b3097226b95a14c5325cff Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 30 Jun 2016 10:56:56 +0200 Subject: [PATCH 2/8] API support for Award Emoji on Snippets --- CHANGELOG | 2 +- lib/api/award_emoji.rb | 30 ++++++++++----- spec/requests/api/award_emoji_spec.rb | 55 ++++++++++++++++++++++++--- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 786e9113af2..2344d9e36e4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -281,6 +281,7 @@ v 8.11.0 - Clean up unused routes (Josef Strzibny) - Fix issue on empty project to allow developers to only push to protected branches if given permission - API: Add enpoints for pipelines + - Emoji can be awarded on Snippets !4456 - Add green outline to New Branch button. !5447 (winniehell) - Optimize generating of cache keys for issues and notes - Fix repository push email formatting in Outlook @@ -508,7 +509,6 @@ v 8.10.0 - Updated project header design - Issuable collapsed assignee tooltip is now the users name - Fix compare view not changing code view rendering style - - Emoji can be awarded on Snippets !4456 - Exclude email check from the standard health check - Updated layout for Projects, Groups, Users on Admin area. !4424 - Fix changing issue state columns in milestone view diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index 2898e8222fa..ecce75cd413 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -87,9 +87,7 @@ module API helpers do def can_read_awardable? - ability = "read_#{awardable.class.to_s.underscore}".to_sym - - can?(current_user, ability, awardable) + can?(current_user, ability_name(awardable), awardable) end def can_award_awardable? @@ -100,18 +98,30 @@ module API @awardable ||= begin if params.include?(:note_id) - noteable.notes.find(params[:note_id]) + note_id = params[:note_id] + params.delete(:note_id) + + awardable.notes.find(note_id) + elsif params.include?(:issue_id) + user_project.issues.find(params[:issue_id]) + elsif params.include?(:merge_request_id) + user_project.merge_requests.find(params[:merge_request_id]) else - noteable + user_project.snippets.find(params[:snippet_id]) end end end - def noteable - if params.include?(:issue_id) - user_project.issues.find(params[:issue_id]) - else - user_project.merge_requests.find(params[:merge_request_id]) + def ability_name(awardable) + case awardable + when Note + ability_name(awardable.noteable) + when Snippet + :read_project_snippet + when MergeRequest + :read_merge_request + when Issue + :read_issue end end end diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb index f55702794f6..f94ed37ddbc 100644 --- a/spec/requests/api/award_emoji_spec.rb +++ b/spec/requests/api/award_emoji_spec.rb @@ -4,7 +4,7 @@ describe API::API, api: true do include ApiHelpers let(:user) { create(:user) } let!(:project) { create(:project) } - let(:issue) { create(:issue, project: project) } + let(:issue) { create(:issue, project: project, author: user) } let!(:award_emoji) { create(:award_emoji, awardable: issue, user: user) } let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) } let!(:downvote) { create(:award_emoji, :downvote, awardable: merge_request, user: user) } @@ -14,9 +14,6 @@ describe API::API, api: true do describe "GET /projects/:id/awardable/:awardable_id/award_emoji" do context 'on an issue' do - let(:issue) { create(:issue, project: project, author: user) } - let!(:award_emoji) { create(:award_emoji, awardable: issue, user: user) } - it "returns an array of award_emoji" do get api("/projects/#{project.id}/issues/#{issue.id}/award_emoji", user) @@ -43,7 +40,16 @@ describe API::API, api: true do end context 'on a snippet' do - it 'returns the awarded ' + let(:snippet) { create(:project_snippet, :public, project: project) } + let!(:award) { create(:award_emoji, awardable: snippet) } + + it 'returns the awarded emoji' do + get api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji", user) + + expect(response).to have_http_status(200) + expect(json_response).to be_an Array + expect(json_response.first['name']).to eq(award.name) + end end context 'when the user has no access' do @@ -98,6 +104,20 @@ describe API::API, api: true do end end + context 'on a snippet' do + let(:snippet) { create(:project_snippet, :public, project: project) } + let!(:award) { create(:award_emoji, awardable: snippet) } + + it 'returns the awarded emoji' do + get api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji/#{award.id}", user) + + expect(response).to have_http_status(200) + expect(json_response['name']).to eq(award.name) + expect(json_response['awardable_id']).to eq(snippet.id) + expect(json_response['awardable_type']).to eq("Snippet") + end + end + context 'when the user has no access' do it 'returns a status code 404' do user1 = create(:user) @@ -167,6 +187,18 @@ describe API::API, api: true do end end end + + context 'on a snippet' do + it 'creates a new award emoji' do + snippet = create(:project_snippet, :public, project: project) + + post api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji", user), name: 'blowfish' + + expect(response).to have_http_status(201) + expect(json_response['name']).to eq('blowfish') + expect(json_response['user']['username']).to eq(user.username) + end + end end describe "POST /projects/:id/awardable/:awardable_id/notes/:note_id/award_emoji" do @@ -236,6 +268,19 @@ describe API::API, api: true do expect(response).to have_http_status(404) end end + + context 'when the awardable is a Snippet' do + let(:snippet) { create(:project_snippet, :public, project: project) } + let!(:award) { create(:award_emoji, awardable: snippet, user: user) } + + it 'deletes the award' do + expect do + delete api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji/#{award.id}", user) + end.to change { snippet.award_emoji.count }.from(1).to(0) + + expect(response).to have_http_status(200) + end + end end describe 'DELETE /projects/:id/awardable/:awardable_id/award_emoji/:award_emoji_id' do From fe0433984c7a089341d0f8b682dbe40d9dab2dec Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Wed, 27 Jul 2016 10:10:07 +0200 Subject: [PATCH 3/8] API docs for award emoji on Snippets [ci skip] --- doc/api/award_emoji.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/api/award_emoji.md b/doc/api/award_emoji.md index 72ec99b7c56..61a6256a1c1 100644 --- a/doc/api/award_emoji.md +++ b/doc/api/award_emoji.md @@ -1,12 +1,13 @@ # Award Emoji -> [Introduced][ce-4575] in GitLab 8.9. +> [Introduced][ce-4575] in GitLab 8.9, Snippet support in 8.11 + An awarded emoji tells a thousand words, and can be awarded on issues, merge -requests and notes/comments. Issues, merge requests and notes are further called +requests, snippets, and notes/comments. Issues, merge requests, snippets, and notes are further called `awardables`. -## Issues and merge requests +## Issues, merge requests, and snippets ### List an awardable's award emoji @@ -15,6 +16,7 @@ Gets a list of all award emoji ``` GET /projects/:id/issues/:issue_id/award_emoji GET /projects/:id/merge_requests/:merge_request_id/award_emoji +GET /projects/:id/snippets/:snippet_id/award_emoji ``` Parameters: @@ -69,11 +71,12 @@ Example Response: ### Get single award emoji -Gets a single award emoji from an issue or merge request. +Gets a single award emoji from an issue, snippet, or merge request. ``` GET /projects/:id/issues/:issue_id/award_emoji/:award_id GET /projects/:id/merge_requests/:merge_request_id/award_emoji/:award_id +GET /projects/:id/snippets/:snippets_id/award_emoji/:award_id ``` Parameters: @@ -116,6 +119,7 @@ This end point creates an award emoji on the specified resource ``` POST /projects/:id/issues/:issue_id/award_emoji POST /projects/:id/merge_requests/:merge_request_id/award_emoji +POST /projects/:id/snippets/:snippets_id/award_emoji ``` Parameters: @@ -159,6 +163,7 @@ admins or the author of the award. Status code 200 on success, 401 if unauthoriz ``` DELETE /projects/:id/issues/:issue_id/award_emoji/:award_id DELETE /projects/:id/merge_requests/:merge_request_id/award_emoji/:award_id +DELETE /projects/:id/snippets/:snippet_id/award_emoji/:award_id ``` Parameters: @@ -197,7 +202,7 @@ Example Response: ## Award Emoji on Notes The endpoints documented above are available for Notes as well. Notes -are a sub-resource of Issues and Merge Requests. The examples below +are a sub-resource of Issues, Merge Requests, or Snippets. The examples below describe working with Award Emoji on notes for an Issue, but can be easily adapted for notes on a Merge Request. From 412ff80b7b1381485a306df240aab020e9b90801 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Sun, 4 Sep 2016 10:51:12 +0200 Subject: [PATCH 4/8] Start Frontend work, fix routing problem --- .../concerns/toggle_award_emoji.rb | 2 +- .../projects/snippets_controller.rb | 5 +- app/helpers/award_emoji_helper.rb | 13 + app/models/concerns/awardable.rb | 6 + app/models/concerns/issuable.rb | 4 - app/models/note.rb | 4 - app/views/award_emoji/_awards_block.html.haml | 2 +- app/views/projects/snippets/show.html.haml | 2 + app/views/snippets/show.html.haml | 2 + routes.txt | 908 ++++++++++++++++++ 10 files changed, 937 insertions(+), 11 deletions(-) create mode 100644 app/helpers/award_emoji_helper.rb create mode 100644 routes.txt diff --git a/app/controllers/concerns/toggle_award_emoji.rb b/app/controllers/concerns/toggle_award_emoji.rb index 13086da7d5e..3717c49f272 100644 --- a/app/controllers/concerns/toggle_award_emoji.rb +++ b/app/controllers/concerns/toggle_award_emoji.rb @@ -10,7 +10,7 @@ module ToggleAwardEmoji if awardable.user_can_award?(current_user, name) awardable.toggle_award_emoji(name, current_user) - + todoable = to_todoable(awardable) TodoService.new.new_award_emoji(todoable, current_user) if todoable diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index 17ceefec3b8..e290a0eadda 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -1,6 +1,8 @@ class Projects::SnippetsController < Projects::ApplicationController + include ToggleAwardEmoji + before_action :module_enabled - before_action :snippet, only: [:show, :edit, :destroy, :update, :raw] + before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :toggle_award_emoji] # Allow read any snippet before_action :authorize_read_project_snippet!, except: [:new, :create, :index] @@ -80,6 +82,7 @@ class Projects::SnippetsController < Projects::ApplicationController def snippet @snippet ||= @project.snippets.find(params[:id]) end + alias_method :awardable, :snippet def authorize_read_project_snippet! return render_404 unless can?(current_user, :read_project_snippet, @snippet) diff --git a/app/helpers/award_emoji_helper.rb b/app/helpers/award_emoji_helper.rb new file mode 100644 index 00000000000..c358abc52ea --- /dev/null +++ b/app/helpers/award_emoji_helper.rb @@ -0,0 +1,13 @@ +module AwardEmojiHelper + def toggle_award_url(awardable) + unless awardable.is_a?(Snippet) + return url_for([:toggle_award_emoji, @project.namespace.becomes(Namespace), @project, awardable]) + end + + if awardable.is_a?(ProjectSnippet) + toggle_award_emoji_namespace_project_snippet_path(@project.namespace.becomes(Namespace), @project, awardable) + else + toggle_award_emoji_snippet_url(awardable) + end + end +end diff --git a/app/models/concerns/awardable.rb b/app/models/concerns/awardable.rb index d8d4575bb4d..073ac4c1b65 100644 --- a/app/models/concerns/awardable.rb +++ b/app/models/concerns/awardable.rb @@ -71,6 +71,12 @@ module Awardable end end + def user_authored?(current_user) + author = self.respond_to?(:author) ? self.author : self.user + + author == current_user + end + def awarded_emoji?(emoji_name, current_user) award_emoji.where(name: emoji_name, user: current_user).exists? end diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 22231b2e0f0..8e11d4f57cf 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -196,10 +196,6 @@ module Issuable end end - def user_authored?(user) - user == author - end - def subscribed_without_subscriptions?(user) participants(user).include?(user) end diff --git a/app/models/note.rb b/app/models/note.rb index b94e3cff2ce..f2656df028b 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -223,10 +223,6 @@ class Note < ActiveRecord::Base end end - def user_authored?(user) - user == author - end - def award_emoji? can_be_award_emoji? && contains_emoji_only? end diff --git a/app/views/award_emoji/_awards_block.html.haml b/app/views/award_emoji/_awards_block.html.haml index 02efcecc889..fbe3ab912b6 100644 --- a/app/views/award_emoji/_awards_block.html.haml +++ b/app/views/award_emoji/_awards_block.html.haml @@ -1,5 +1,5 @@ - grouped_emojis = awardable.grouped_awards(with_thumbs: inline) -.awards.js-awards-block{ class: ("hidden" if !inline && grouped_emojis.empty?), data: { award_url: url_for([:toggle_award_emoji, @project.namespace.becomes(Namespace), @project, awardable]) } } +.awards.js-awards-block{ class: ("hidden" if !inline && grouped_emojis.empty?), data: { award_url: toggle_award_url(awardable) } } - awards_sort(grouped_emojis).each do |emoji, awards| %button.btn.award-control.js-emoji-btn.has-tooltip{ type: "button", class: (award_active_class(awards, current_user)), data: { placement: "bottom", title: award_user_list(awards, current_user) } } = emoji_icon(emoji, sprite: false) diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index b70fda88a79..7f72e15ca8f 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -11,4 +11,6 @@ = link_to 'Raw', raw_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-sm", target: "_blank" = render 'shared/snippets/blob' += render 'award_emoji/awards_block', awardable: @snippet, inline: true + %div#notes= render "projects/notes/notes_with_form" diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index fa403da8f79..cd89155c616 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -10,3 +10,5 @@ = clipboard_button(clipboard_target: ".blob-content[data-blob-id='#{@snippet.id}']") = link_to 'Raw', raw_snippet_path(@snippet), class: "btn btn-sm", target: "_blank" = render 'shared/snippets/blob' + += render 'award_emoji/awards_block', awardable: @snippet, inline: true \ No newline at end of file diff --git a/routes.txt b/routes.txt new file mode 100644 index 00000000000..30172ed674a --- /dev/null +++ b/routes.txt @@ -0,0 +1,908 @@ + Prefix Verb URI Pattern Controller#Action + teaspoon /teaspoon Teaspoon::Engine + letter_opener_web /rails/letter_opener LetterOpenerWeb::Engine + ci_ci_api_api /ci/api Ci::API::API + ci_lint POST /ci/lint(.:format) ci/lints#create + GET /ci/lint(.:format) ci/lints#show + status_ci_project GET /ci/projects/:id/status(.:format) ci/projects#badge + ci_projects GET /ci/projects(.:format) ci/projects#index + ci_project GET /ci/projects/:id(.:format) ci/projects#show + ci_root GET /ci(.:format) ci/projects#index + GET /oauth/authorize/:code(.:format) oauth/authorizations#show + oauth_authorization GET /oauth/authorize(.:format) oauth/authorizations#new + POST /oauth/authorize(.:format) oauth/authorizations#create + DELETE /oauth/authorize(.:format) oauth/authorizations#destroy + oauth_token POST /oauth/token(.:format) doorkeeper/tokens#create + oauth_revoke POST /oauth/revoke(.:format) doorkeeper/tokens#revoke + oauth_applications GET /oauth/applications(.:format) oauth/applications#index + POST /oauth/applications(.:format) oauth/applications#create + new_oauth_application GET /oauth/applications/new(.:format) oauth/applications#new + edit_oauth_application GET /oauth/applications/:id/edit(.:format) oauth/applications#edit + oauth_application GET /oauth/applications/:id(.:format) oauth/applications#show + PATCH /oauth/applications/:id(.:format) oauth/applications#update + PUT /oauth/applications/:id(.:format) oauth/applications#update + DELETE /oauth/applications/:id(.:format) oauth/applications#destroy + oauth_authorized_applications GET /oauth/authorized_applications(.:format) oauth/authorized_applications#index + oauth_authorized_application DELETE /oauth/authorized_applications/:id(.:format) oauth/authorized_applications#destroy + oauth_token_info GET /oauth/token/info(.:format) doorkeeper/token_info#show + autocomplete_users GET /autocomplete/users(.:format) autocomplete#users + GET /autocomplete/users/:id(.:format) autocomplete#user + autocomplete_projects GET /autocomplete/projects(.:format) autocomplete#projects + emojis GET /emojis(.:format) emojis#index + search GET /search(.:format) search#show + search_autocomplete GET /search/autocomplete(.:format) search#autocomplete + jwt_auth GET /jwt/auth(.:format) jwt#auth + api_api /api API::API + sidekiq /admin/sidekiq Sidekiq::Web + health_check GET /health_check(/:checks)(.:format) health_check#index + help GET /help(.:format) help#index + help_shortcuts GET /help/shortcuts(.:format) help#shortcuts + help_ui GET /help/ui(.:format) help#ui + help_page GET /help/*path(.:format) help#show + koding GET /koding(.:format) koding#index + raw_snippet GET /snippets/:id/raw(.:format) snippets#raw + toggle_award_emoji_snippet POST /snippets/:id/toggle_award_emoji(.:format) snippets#toggle_award_emoji + snippets GET /snippets(.:format) snippets#index + POST /snippets(.:format) snippets#create + new_snippet GET /snippets/new(.:format) snippets#new + edit_snippet GET /snippets/:id/edit(.:format) snippets#edit + snippet GET /snippets/:id(.:format) snippets#show + PATCH /snippets/:id(.:format) snippets#update + PUT /snippets/:id(.:format) snippets#update + DELETE /snippets/:id(.:format) snippets#destroy + GET /s/:username(.:format) redirect(301, /u/%{username}/snippets) {:username=>/[a-zA-Z.0-9_\-]+(?/[A-Za-z0-9_-]+/} + decline_invite GET|POST /invites/:id/decline(.:format) invites#decline {:id=>/[A-Za-z0-9_-]+/} + invite GET /invites/:id(.:format) invites#show {:id=>/[A-Za-z0-9_-]+/} + unsubscribe_sent_notification GET /sent_notifications/:id/unsubscribe(.:format) sent_notifications#unsubscribe {:id=>/\h{32}/} + abuse_reports POST /abuse_reports(.:format) abuse_reports#create + new_abuse_report GET /abuse_reports/new(.:format) abuse_reports#new + notification_settings POST /notification_settings(.:format) notification_settings#create + notification_setting PATCH /notification_settings/:id(.:format) notification_settings#update + PUT /notification_settings/:id(.:format) notification_settings#update + personal_access_token_import_github POST /import/github/personal_access_token(.:format) import/github#personal_access_token + status_import_github GET /import/github/status(.:format) import/github#status + callback_import_github GET /import/github/callback(.:format) import/github#callback + jobs_import_github GET /import/github/jobs(.:format) import/github#jobs + import_github POST /import/github(.:format) import/github#create + new_import_github GET /import/github/new(.:format) import/github#new + status_import_gitlab GET /import/gitlab/status(.:format) import/gitlab#status + callback_import_gitlab GET /import/gitlab/callback(.:format) import/gitlab#callback + jobs_import_gitlab GET /import/gitlab/jobs(.:format) import/gitlab#jobs + import_gitlab POST /import/gitlab(.:format) import/gitlab#create + status_import_bitbucket GET /import/bitbucket/status(.:format) import/bitbucket#status + callback_import_bitbucket GET /import/bitbucket/callback(.:format) import/bitbucket#callback + jobs_import_bitbucket GET /import/bitbucket/jobs(.:format) import/bitbucket#jobs + import_bitbucket POST /import/bitbucket(.:format) import/bitbucket#create + status_import_google_code GET /import/google_code/status(.:format) import/google_code#status + callback_import_google_code POST /import/google_code/callback(.:format) import/google_code#callback + jobs_import_google_code GET /import/google_code/jobs(.:format) import/google_code#jobs + new_user_map_import_google_code GET /import/google_code/user_map(.:format) import/google_code#new_user_map + create_user_map_import_google_code POST /import/google_code/user_map(.:format) import/google_code#create_user_map + import_google_code POST /import/google_code(.:format) import/google_code#create + new_import_google_code GET /import/google_code/new(.:format) import/google_code#new + status_import_fogbugz GET /import/fogbugz/status(.:format) import/fogbugz#status + callback_import_fogbugz POST /import/fogbugz/callback(.:format) import/fogbugz#callback + jobs_import_fogbugz GET /import/fogbugz/jobs(.:format) import/fogbugz#jobs + new_user_map_import_fogbugz GET /import/fogbugz/user_map(.:format) import/fogbugz#new_user_map + create_user_map_import_fogbugz POST /import/fogbugz/user_map(.:format) import/fogbugz#create_user_map + import_fogbugz POST /import/fogbugz(.:format) import/fogbugz#create + new_import_fogbugz GET /import/fogbugz/new(.:format) import/fogbugz#new + import_gitlab_project POST /import/gitlab_project(.:format) import/gitlab_projects#create + POST /import/gitlab_project(.:format) import/gitlab_projects#create + new_import_gitlab_project GET /import/gitlab_project/new(.:format) import/gitlab_projects#new + GET /uploads/:model/:mounted_as/:id/:filename(.:format) uploads#show {:model=>/note|user|group|project/, :mounted_as=>/avatar|attachment/, :filename=>/[^\/]+/} + GET /uploads/:model/:mounted_as/:id/:filename(.:format) uploads#show {:model=>/appearance/, :mounted_as=>/logo|header_logo/, :filename=>/.+/} + GET /uploads/:namespace_id/:project_id/:secret/:filename(.:format) projects/uploads#show {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+/, :filename=>/[^\/]+/} + GET /files/note/:id/:filename(.:format) redirect(301, uploads/note/attachment/%{id}/%{filename}) {:filename=>/[^\/]+/} + trending_explore_projects GET /explore/projects/trending(.:format) explore/projects#trending + starred_explore_projects GET /explore/projects/starred(.:format) explore/projects#starred + explore_projects GET /explore/projects(.:format) explore/projects#index + explore_groups GET /explore/groups(.:format) explore/groups#index + explore_snippets GET /explore/snippets(.:format) explore/snippets#index + explore_root GET /explore(.:format) explore/projects#trending + public GET /public(.:format) explore/projects#index + public_projects GET /public/projects(.:format) explore/projects#index + admin_user_key GET /admin/users/:user_id/keys/:id(.:format) admin/keys#show {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} + DELETE /admin/users/:user_id/keys/:id(.:format) admin/keys#destroy {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} + admin_user_identities GET /admin/users/:user_id/identities(.:format) admin/identities#index {:user_id=>/[a-zA-Z.\/0-9_\-]+/} + POST /admin/users/:user_id/identities(.:format) admin/identities#create {:user_id=>/[a-zA-Z.\/0-9_\-]+/} + new_admin_user_identity GET /admin/users/:user_id/identities/new(.:format) admin/identities#new {:user_id=>/[a-zA-Z.\/0-9_\-]+/} + edit_admin_user_identity GET /admin/users/:user_id/identities/:id/edit(.:format) admin/identities#edit {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} + admin_user_identity PATCH /admin/users/:user_id/identities/:id(.:format) admin/identities#update {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} + PUT /admin/users/:user_id/identities/:id(.:format) admin/identities#update {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} + DELETE /admin/users/:user_id/identities/:id(.:format) admin/identities#destroy {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} + projects_admin_user GET /admin/users/:id/projects(.:format) admin/users#projects {:id=>/[a-zA-Z.\/0-9_\-]+/} + keys_admin_user GET /admin/users/:id/keys(.:format) admin/users#keys {:id=>/[a-zA-Z.\/0-9_\-]+/} + groups_admin_user GET /admin/users/:id/groups(.:format) admin/users#groups {:id=>/[a-zA-Z.\/0-9_\-]+/} + block_admin_user PUT /admin/users/:id/block(.:format) admin/users#block {:id=>/[a-zA-Z.\/0-9_\-]+/} + unblock_admin_user PUT /admin/users/:id/unblock(.:format) admin/users#unblock {:id=>/[a-zA-Z.\/0-9_\-]+/} + unlock_admin_user PUT /admin/users/:id/unlock(.:format) admin/users#unlock {:id=>/[a-zA-Z.\/0-9_\-]+/} + confirm_admin_user PUT /admin/users/:id/confirm(.:format) admin/users#confirm {:id=>/[a-zA-Z.\/0-9_\-]+/} + impersonate_admin_user POST /admin/users/:id/impersonate(.:format) admin/users#impersonate {:id=>/[a-zA-Z.\/0-9_\-]+/} + disable_two_factor_admin_user PATCH /admin/users/:id/disable_two_factor(.:format) admin/users#disable_two_factor {:id=>/[a-zA-Z.\/0-9_\-]+/} + remove_email_admin_user DELETE /admin/users/:id/remove/:email_id(.:format) admin/users#remove_email {:id=>/[a-zA-Z.\/0-9_\-]+/} + admin_users GET /admin/users(.:format) admin/users#index + POST /admin/users(.:format) admin/users#create + new_admin_user GET /admin/users/new(.:format) admin/users#new + edit_admin_user GET /admin/users/:id/edit(.:format) admin/users#edit {:id=>/[a-zA-Z.\/0-9_\-]+/} + admin_user GET /admin/users/:id(.:format) admin/users#show {:id=>/[a-zA-Z.\/0-9_\-]+/} + PATCH /admin/users/:id(.:format) admin/users#update {:id=>/[a-zA-Z.\/0-9_\-]+/} + PUT /admin/users/:id(.:format) admin/users#update {:id=>/[a-zA-Z.\/0-9_\-]+/} + DELETE /admin/users/:id(.:format) admin/users#destroy {:id=>/[a-zA-Z.\/0-9_\-]+/} + admin_impersonation DELETE /admin/impersonation(.:format) admin/impersonations#destroy + admin_abuse_reports GET /admin/abuse_reports(.:format) admin/abuse_reports#index + admin_abuse_report DELETE /admin/abuse_reports/:id(.:format) admin/abuse_reports#destroy + mark_as_ham_admin_spam_log POST /admin/spam_logs/:id/mark_as_ham(.:format) admin/spam_logs#mark_as_ham + admin_spam_logs GET /admin/spam_logs(.:format) admin/spam_logs#index + admin_spam_log DELETE /admin/spam_logs/:id(.:format) admin/spam_logs#destroy + admin_applications GET /admin/applications(.:format) admin/applications#index + POST /admin/applications(.:format) admin/applications#create + new_admin_application GET /admin/applications/new(.:format) admin/applications#new + edit_admin_application GET /admin/applications/:id/edit(.:format) admin/applications#edit + admin_application GET /admin/applications/:id(.:format) admin/applications#show + PATCH /admin/applications/:id(.:format) admin/applications#update + PUT /admin/applications/:id(.:format) admin/applications#update + DELETE /admin/applications/:id(.:format) admin/applications#destroy + members_update_admin_group PUT /admin/groups/:id/members_update(.:format) admin/groups#members_update {:id=>/[^\/]+/} + admin_groups GET /admin/groups(.:format) admin/groups#index + POST /admin/groups(.:format) admin/groups#create + new_admin_group GET /admin/groups/new(.:format) admin/groups#new + edit_admin_group GET /admin/groups/:id/edit(.:format) admin/groups#edit {:id=>/[^\/]+/} + admin_group GET /admin/groups/:id(.:format) admin/groups#show {:id=>/[^\/]+/} + PATCH /admin/groups/:id(.:format) admin/groups#update {:id=>/[^\/]+/} + PUT /admin/groups/:id(.:format) admin/groups#update {:id=>/[^\/]+/} + DELETE /admin/groups/:id(.:format) admin/groups#destroy {:id=>/[^\/]+/} + admin_deploy_keys GET /admin/deploy_keys(.:format) admin/deploy_keys#index + POST /admin/deploy_keys(.:format) admin/deploy_keys#create + new_admin_deploy_key GET /admin/deploy_keys/new(.:format) admin/deploy_keys#new + admin_deploy_key DELETE /admin/deploy_keys/:id(.:format) admin/deploy_keys#destroy + admin_hook_test GET /admin/hooks/:hook_id/test(.:format) admin/hooks#test + admin_hooks GET /admin/hooks(.:format) admin/hooks#index + POST /admin/hooks(.:format) admin/hooks#create + admin_hook DELETE /admin/hooks/:id(.:format) admin/hooks#destroy + preview_admin_broadcast_messages POST /admin/broadcast_messages/preview(.:format) admin/broadcast_messages#preview + admin_broadcast_messages GET /admin/broadcast_messages(.:format) admin/broadcast_messages#index + POST /admin/broadcast_messages(.:format) admin/broadcast_messages#create + edit_admin_broadcast_message GET /admin/broadcast_messages/:id/edit(.:format) admin/broadcast_messages#edit + admin_broadcast_message PATCH /admin/broadcast_messages/:id(.:format) admin/broadcast_messages#update + PUT /admin/broadcast_messages/:id(.:format) admin/broadcast_messages#update + DELETE /admin/broadcast_messages/:id(.:format) admin/broadcast_messages#destroy + admin_logs GET /admin/logs(.:format) admin/logs#show + admin_health_check GET /admin/health_check(.:format) admin/health_check#show + admin_background_jobs GET /admin/background_jobs(.:format) admin/background_jobs#show + admin_system_info GET /admin/system_info(.:format) admin/system_info#show + admin_requests_profiles GET /admin/requests_profiles(.:format) admin/requests_profiles#index + admin_requests_profile GET /admin/requests_profiles/:name(.:format) admin/requests_profiles#show {:name=>/.+\.html/} + admin_namespaces_projects GET /admin/projects(.:format) admin/projects#index + admin_namespace_projects_root GET /admin/projects/:namespace_id(.:format) admin/projects#show {:namespace_id=>/[a-zA-Z.0-9_\-]+/} + transfer_admin_namespace_project PUT /admin/projects/:namespace_id/:id/transfer(.:format) admin/projects#transfer {:id=>/[a-zA-Z.0-9_\-]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/} + repository_check_admin_namespace_project POST /admin/projects/:namespace_id/:id/repository_check(.:format) admin/projects#repository_check {:id=>/[a-zA-Z.0-9_\-]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/} + admin_namespace_project_runner_projects POST /admin/projects/:namespace_id/:project_id/runner_projects(.:format) admin/runner_projects#create {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+/} + admin_namespace_project_runner_project DELETE /admin/projects/:namespace_id/:project_id/runner_projects/:id(.:format) admin/runner_projects#destroy {:id=>/[a-zA-Z.0-9_\-]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+/} + admin_namespace_projects GET /admin/projects/:namespace_id(.:format) admin/projects#index {:namespace_id=>/[a-zA-Z.0-9_\-]+/} + admin_namespace_project GET /admin/projects/:namespace_id/:id(.:format) admin/projects#show {:id=>/[a-zA-Z.0-9_\-]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/} + preview_admin_appearances GET /admin/appearance/preview(.:format) admin/appearances#preview + logo_admin_appearances DELETE /admin/appearance/logo(.:format) admin/appearances#logo + header_logos_admin_appearances DELETE /admin/appearance/header_logos(.:format) admin/appearances#header_logos + admin_appearances POST /admin/appearance(.:format) admin/appearances#create + GET /admin/appearance(.:format) admin/appearances#show + PATCH /admin/appearance(.:format) admin/appearances#update + PUT /admin/appearance(.:format) admin/appearances#update + admin_application_settings_services GET /admin/application_settings/services(.:format) admin/services#index + edit_admin_application_settings_service GET /admin/application_settings/services/:id/edit(.:format) admin/services#edit + admin_application_settings_service PATCH /admin/application_settings/services/:id(.:format) admin/services#update + PUT /admin/application_settings/services/:id(.:format) admin/services#update + reset_runners_token_admin_application_settings PUT /admin/application_settings/reset_runners_token(.:format) admin/application_settings#reset_runners_token + reset_health_check_token_admin_application_settings PUT /admin/application_settings/reset_health_check_token(.:format) admin/application_settings#reset_health_check_token + clear_repository_check_states_admin_application_settings PUT /admin/application_settings/clear_repository_check_states(.:format) admin/application_settings#clear_repository_check_states + admin_application_settings GET /admin/application_settings(.:format) admin/application_settings#show + PATCH /admin/application_settings(.:format) admin/application_settings#update + PUT /admin/application_settings(.:format) admin/application_settings#update + admin_labels GET /admin/labels(.:format) admin/labels#index + POST /admin/labels(.:format) admin/labels#create + new_admin_label GET /admin/labels/new(.:format) admin/labels#new + edit_admin_label GET /admin/labels/:id/edit(.:format) admin/labels#edit + admin_label GET /admin/labels/:id(.:format) admin/labels#show + PATCH /admin/labels/:id(.:format) admin/labels#update + PUT /admin/labels/:id(.:format) admin/labels#update + DELETE /admin/labels/:id(.:format) admin/labels#destroy + resume_admin_runner GET /admin/runners/:id/resume(.:format) admin/runners#resume + pause_admin_runner GET /admin/runners/:id/pause(.:format) admin/runners#pause + admin_runners GET /admin/runners(.:format) admin/runners#index + admin_runner GET /admin/runners/:id(.:format) admin/runners#show + PATCH /admin/runners/:id(.:format) admin/runners#update + PUT /admin/runners/:id(.:format) admin/runners#update + DELETE /admin/runners/:id(.:format) admin/runners#destroy + cancel_all_admin_builds POST /admin/builds/cancel_all(.:format) admin/builds#cancel_all + admin_builds GET /admin/builds(.:format) admin/builds#index + admin_root GET /admin(.:format) admin/dashboard#index + audit_log_profile GET /profile/audit_log(.:format) profiles#audit_log + applications_profile GET /profile/applications(.:format) oauth/applications#index + reset_private_token_profile PUT /profile/reset_private_token(.:format) profiles#reset_private_token + update_username_profile PUT /profile/update_username(.:format) profiles#update_username + unlink_profile_account DELETE /profile/account/unlink(.:format) profiles/accounts#unlink + profile_account GET /profile/account(.:format) profiles/accounts#show + profile_notifications GET /profile/notifications(.:format) profiles/notifications#show + PATCH /profile/notifications(.:format) profiles/notifications#update + PUT /profile/notifications(.:format) profiles/notifications#update + reset_profile_password PUT /profile/password/reset(.:format) profiles/passwords#reset + profile_password POST /profile/password(.:format) profiles/passwords#create + new_profile_password GET /profile/password/new(.:format) profiles/passwords#new + edit_profile_password GET /profile/password/edit(.:format) profiles/passwords#edit + PATCH /profile/password(.:format) profiles/passwords#update + PUT /profile/password(.:format) profiles/passwords#update + profile_preferences GET /profile/preferences(.:format) profiles/preferences#show + PATCH /profile/preferences(.:format) profiles/preferences#update + PUT /profile/preferences(.:format) profiles/preferences#update + profile_keys GET /profile/keys(.:format) profiles/keys#index + POST /profile/keys(.:format) profiles/keys#create + new_profile_key GET /profile/keys/new(.:format) profiles/keys#new + profile_key GET /profile/keys/:id(.:format) profiles/keys#show + DELETE /profile/keys/:id(.:format) profiles/keys#destroy + profile_emails GET /profile/emails(.:format) profiles/emails#index + POST /profile/emails(.:format) profiles/emails#create + profile_email DELETE /profile/emails/:id(.:format) profiles/emails#destroy + profile_avatar DELETE /profile/avatar(.:format) profiles/avatars#destroy + revoke_profile_personal_access_token PUT /profile/personal_access_tokens/:id/revoke(.:format) profiles/personal_access_tokens#revoke + profile_personal_access_tokens GET /profile/personal_access_tokens(.:format) profiles/personal_access_tokens#index + POST /profile/personal_access_tokens(.:format) profiles/personal_access_tokens#create + create_u2f_profile_two_factor_auth POST /profile/two_factor_auth/create_u2f(.:format) profiles/two_factor_auths#create_u2f + codes_profile_two_factor_auth POST /profile/two_factor_auth/codes(.:format) profiles/two_factor_auths#codes + skip_profile_two_factor_auth PATCH /profile/two_factor_auth/skip(.:format) profiles/two_factor_auths#skip + profile_two_factor_auth POST /profile/two_factor_auth(.:format) profiles/two_factor_auths#create + GET /profile/two_factor_auth(.:format) profiles/two_factor_auths#show + DELETE /profile/two_factor_auth(.:format) profiles/two_factor_auths#destroy + profile_u2f_registration DELETE /profile/u2f_registrations/:id(.:format) profiles/u2f_registrations#destroy + profile GET /profile(.:format) profiles#show + PATCH /profile(.:format) profiles#update + PUT /profile(.:format) profiles#update + user_calendar GET /u/:username/calendar(.:format) users#calendar {:username=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :group_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :group_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :group_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + remove_fork_namespace_project DELETE /:namespace_id/:id/remove_fork(.:format) projects#remove_fork {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + archive_namespace_project POST /:namespace_id/:id/archive(.:format) projects#archive {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + unarchive_namespace_project POST /:namespace_id/:id/unarchive(.:format) projects#unarchive {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + housekeeping_namespace_project POST /:namespace_id/:id/housekeeping(.:format) projects#housekeeping {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + toggle_star_namespace_project POST /:namespace_id/:id/toggle_star(.:format) projects#toggle_star {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + preview_markdown_namespace_project POST /:namespace_id/:id/preview_markdown(.:format) projects#preview_markdown {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + export_namespace_project POST /:namespace_id/:id/export(.:format) projects#export {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + remove_export_namespace_project POST /:namespace_id/:id/remove_export(.:format) projects#remove_export {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + generate_new_export_namespace_project POST /:namespace_id/:id/generate_new_export(.:format) projects#generate_new_export {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + download_export_namespace_project GET /:namespace_id/:id/download_export(.:format) projects#download_export {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + autocomplete_sources_namespace_project GET /:namespace_id/:id/autocomplete_sources(.:format) projects#autocomplete_sources {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + activity_namespace_project GET /:namespace_id/:id/activity(.:format) projects#activity {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + refs_namespace_project GET /:namespace_id/:id/refs(.:format) projects#refs {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + namespace_project_info_refs GET /:namespace_id/:project_id/info/refs(.:format) projects/git_http#info_refs {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} + namespace_project_git_upload_pack POST /:namespace_id/:project_id/git-upload-pack(.:format) projects/git_http#git_upload_pack {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} + namespace_project_git_receive_pack POST /:namespace_id/:project_id/git-receive-pack(.:format) projects/git_http#git_receive_pack {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} + namespace_project_info_lfs_objects_batch POST /:namespace_id/:project_id/info/lfs/objects/batch(.:format) projects/lfs_api#batch {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} + namespace_project_info_lfs_objects POST /:namespace_id/:project_id/info/lfs/objects(.:format) projects/lfs_api#deprecated {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} + GET /:namespace_id/:project_id/info/lfs/objects/*oid(.:format) projects/lfs_api#deprecated {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} + GET /:namespace_id/:project_id/gitlab-lfs/objects/*oid(.:format) projects/lfs_storage#download {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} + PUT /:namespace_id/:project_id/gitlab-lfs/objects/*oid/*size/authorize(.:format) projects/lfs_storage#upload_authorize {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} + PUT /:namespace_id/:project_id/gitlab-lfs/objects/*oid/*size(.:format) projects/lfs_storage#upload_finalize {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} + GET /:namespace_id/:project_id/info/refs(.:format) redirect(301) {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?false} + namespace_project_blob GET /:namespace_id/:project_id/blob/*id(.:format) projects/blob#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?false} + DELETE /:namespace_id/:project_id/blob/*id(.:format) projects/blob#destroy {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?false} + PUT /:namespace_id/:project_id/blob/*id(.:format) projects/blob#update {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?false} + POST /:namespace_id/:project_id/blob/*id(.:format) projects/blob#create {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?false} + namespace_project_raw GET /:namespace_id/:project_id/raw/*id(.:format) projects/raw#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/(html|js)/} + namespace_project_tree GET /:namespace_id/:project_id/tree/*id(.:format) projects/tree#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/(html|js)/} + namespace_project_find_file GET /:namespace_id/:project_id/find_file/*id(.:format) projects/find_file#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/html/} + namespace_project_files GET /:namespace_id/:project_id/files/*id(.:format) projects/find_file#list {:id=>/(?:[^.]|\.(?!json$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/json/} + namespace_project_create_dir POST /:namespace_id/:project_id/create_dir/*id(.:format) projects/tree#create_dir {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/(html|js)/} + namespace_project_commits GET /:namespace_id/:project_id/commits/*id(.:format) projects/commits#show {:id=>/(?:[^.]|\.(?!atom$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/atom/} + namespace_project_avatar GET /:namespace_id/:project_id/avatar(.:format) projects/avatars#show {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :to=>/.+/} + namespace_project_network GET /:namespace_id/:project_id/network/:id projects/network#show {:id=>/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/(zip|tar|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/} + namespace_project_repository POST /:namespace_id/:project_id/repository(.:format) projects/repositories#create {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.*/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.*/} + commits_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/commits(.:format) projects/merge_requests#commits {:id=>/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} + DELETE /:namespace_id/:project_id/merge_requests/:merge_request_id/discussions/:id/resolve(.:format) projects/discussions#unresolve {:id=>/\h{40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} + namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#index {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} + browse_namespace_project_build_artifacts GET /:namespace_id/:project_id/builds/:build_id/artifacts/browse(/*path) projects/artifacts#browse {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} + file_namespace_project_build_artifacts GET /:namespace_id/:project_id/builds/:build_id/artifacts/file/*path projects/artifacts#file {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} + keep_namespace_project_build_artifacts POST /:namespace_id/:project_id/builds/:build_id/artifacts/keep(.:format) projects/artifacts#keep {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} + namespace_project_builds GET /:namespace_id/:project_id/builds(.:format) projects/builds#index {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ + (?! + (?# doesn't begins with) + \/| (?# rule #6) + (?# doesn't contain) + .*(?: + [\/.]\.| (?# rule #1,3) + \/\/| (?# rule #6) + @\{| (?# rule #8) + \\ (?# rule #9) + ) + ) + [^\000-\040\177~^:?*\[]+ (?# rule #4-5) + (?# doesn't end with) + (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.\/0-9_\-#%+]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.\/0-9_\-#%+]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.\/0-9_\-#%+]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.\/0-9_\-#%+]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.\/0-9_\-#%+]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/} + namespace_project_uploads POST /:namespace_id/:project_id/uploads(.:format) projects/uploads#create {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/svg/} + coverage_namespace_project_badges GET /:namespace_id/:project_id/badges/*ref/coverage(.:format) projects/badges#coverage {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/svg/} + namespace_project_badges GET /:namespace_id/:project_id/badges(.:format) projects/badges#index {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + namespace_project GET /:namespace_id/:id(.:format) projects#show {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + PATCH /:namespace_id/:id(.:format) projects#update {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + PUT /:namespace_id/:id(.:format) projects#update {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + DELETE /:namespace_id/:id(.:format) projects#destroy {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} + GET /:username.keys(.:format) profiles/keys#get_keys {:username=>/.*/} + GET /:id(.:format) namespaces#show {:id=>/(?:[^.]|\.(?!atom$))+/, :format=>/atom/} + GET /health_check(/:checks)(.:format) health_check/health_check#index + +Routes for Teaspoon::Engine: + root GET / teaspoon/suite#index +fixture GET /fixtures/*filename(.:format) teaspoon/suite#fixtures + suite GET /:suite(.:format) teaspoon/suite#show {:suite=>"default"} + POST /:suite/:hook(.:format) teaspoon/suite#hook {:suite=>"default", :hook=>"default"} + +Routes for LetterOpenerWeb::Engine: +clear_letters DELETE /clear(.:format) letter_opener_web/letters#clear +delete_letter DELETE /:id(.:format) letter_opener_web/letters#destroy + letters GET / letter_opener_web/letters#index + letter GET /:id(/:style)(.:format) letter_opener_web/letters#show + GET /:id/attachments/:file(.:format) letter_opener_web/letters#attachment From e8dd0d54cb1e82d142978224a4e062a705cae2cf Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Wed, 7 Sep 2016 14:48:43 +0200 Subject: [PATCH 5/8] Fix tests for Snippets toggling awards Also incorporate feedback --- CHANGELOG | 2 +- app/helpers/award_emoji_helper.rb | 10 +- app/helpers/gitlab_routing_helper.rb | 8 + doc/api/award_emoji.md | 6 +- lib/api/award_emoji.rb | 23 +- routes.txt | 908 ------------------- spec/controllers/snippets_controller_spec.rb | 10 +- spec/requests/api/award_emoji_spec.rb | 4 +- 8 files changed, 32 insertions(+), 939 deletions(-) delete mode 100644 routes.txt diff --git a/CHANGELOG b/CHANGELOG index 2344d9e36e4..700a7a28bd0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -42,6 +42,7 @@ v 8.12.0 (unreleased) - Move parsing of sidekiq ps into helper !6245 (pascalbetz) - Added go to issue boards keyboard shortcut - Expose `sha` and `merge_commit_sha` in merge request API (Ben Boeckel) + - Emoji can be awarded on Snippets !4456 - Set path for all JavaScript cookies to honor GitLab's subdirectory setting !5627 (Mike Greiling) - Fix blame table layout width - Fix bug where pagination is still displayed despite all todos marked as done (ClemMakesApps) @@ -281,7 +282,6 @@ v 8.11.0 - Clean up unused routes (Josef Strzibny) - Fix issue on empty project to allow developers to only push to protected branches if given permission - API: Add enpoints for pipelines - - Emoji can be awarded on Snippets !4456 - Add green outline to New Branch button. !5447 (winniehell) - Optimize generating of cache keys for issues and notes - Fix repository push email formatting in Outlook diff --git a/app/helpers/award_emoji_helper.rb b/app/helpers/award_emoji_helper.rb index c358abc52ea..aa134cea31c 100644 --- a/app/helpers/award_emoji_helper.rb +++ b/app/helpers/award_emoji_helper.rb @@ -1,13 +1,9 @@ module AwardEmojiHelper def toggle_award_url(awardable) - unless awardable.is_a?(Snippet) - return url_for([:toggle_award_emoji, @project.namespace.becomes(Namespace), @project, awardable]) - end - - if awardable.is_a?(ProjectSnippet) - toggle_award_emoji_namespace_project_snippet_path(@project.namespace.becomes(Namespace), @project, awardable) + if @project + url_for([:toggle_award_emoji, @project.namespace.becomes(Namespace), @project, awardable]) else - toggle_award_emoji_snippet_url(awardable) + url_for([:toggle_award_emoji, awardable]) end end end diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb index a322a90cc4e..6277c138479 100644 --- a/app/helpers/gitlab_routing_helper.rb +++ b/app/helpers/gitlab_routing_helper.rb @@ -98,6 +98,14 @@ module GitlabRoutingHelper end end + def toggle_award_emoji_personal_snippet_path(*args) + toggle_award_emoji_snippet_path(*args) + end + + def toggle_award_emoji_namespace_project_project_snippet_path(*args) + toggle_award_emoji_namespace_project_snippet_path(*args) + end + ## Members def project_members_url(project, *args) namespace_project_project_members_url(project.namespace, project) diff --git a/doc/api/award_emoji.md b/doc/api/award_emoji.md index 61a6256a1c1..c464e3f3f71 100644 --- a/doc/api/award_emoji.md +++ b/doc/api/award_emoji.md @@ -1,6 +1,6 @@ # Award Emoji -> [Introduced][ce-4575] in GitLab 8.9, Snippet support in 8.11 +> [Introduced][ce-4575] in GitLab 8.9, Snippet support in 8.12 An awarded emoji tells a thousand words, and can be awarded on issues, merge @@ -76,7 +76,7 @@ Gets a single award emoji from an issue, snippet, or merge request. ``` GET /projects/:id/issues/:issue_id/award_emoji/:award_id GET /projects/:id/merge_requests/:merge_request_id/award_emoji/:award_id -GET /projects/:id/snippets/:snippets_id/award_emoji/:award_id +GET /projects/:id/snippets/:snippet_id/award_emoji/:award_id ``` Parameters: @@ -119,7 +119,7 @@ This end point creates an award emoji on the specified resource ``` POST /projects/:id/issues/:issue_id/award_emoji POST /projects/:id/merge_requests/:merge_request_id/award_emoji -POST /projects/:id/snippets/:snippets_id/award_emoji +POST /projects/:id/snippets/:snippet_id/award_emoji ``` Parameters: diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index ecce75cd413..2461a783ea8 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -1,12 +1,12 @@ module API class AwardEmoji < Grape::API before { authenticate! } - AWARDABLES = [Issue, MergeRequest, Snippet] + AWARDABLES = %w[issue merge_request snippet] resource :projects do AWARDABLES.each do |awardable_type| - awardable_string = awardable_type.to_s.underscore.pluralize - awardable_id_string = "#{awardable_type.to_s.underscore}_id" + awardable_string = awardable_type.pluralize + awardable_id_string = "#{awardable_type}_id" [ ":id/#{awardable_string}/:#{awardable_id_string}/award_emoji", ":id/#{awardable_string}/:#{awardable_id_string}/notes/:note_id/award_emoji" @@ -87,7 +87,7 @@ module API helpers do def can_read_awardable? - can?(current_user, ability_name(awardable), awardable) + can?(current_user, read_ability(awardable), awardable) end def can_award_awardable? @@ -98,8 +98,7 @@ module API @awardable ||= begin if params.include?(:note_id) - note_id = params[:note_id] - params.delete(:note_id) + note_id = params.delete(:note_id) awardable.notes.find(note_id) elsif params.include?(:issue_id) @@ -112,16 +111,12 @@ module API end end - def ability_name(awardable) + def read_ability(awardable) case awardable when Note - ability_name(awardable.noteable) - when Snippet - :read_project_snippet - when MergeRequest - :read_merge_request - when Issue - :read_issue + read_ability(awardable.noteable) + else + :"read_#{awardable.class.to_s.underscore}" end end end diff --git a/routes.txt b/routes.txt deleted file mode 100644 index 30172ed674a..00000000000 --- a/routes.txt +++ /dev/null @@ -1,908 +0,0 @@ - Prefix Verb URI Pattern Controller#Action - teaspoon /teaspoon Teaspoon::Engine - letter_opener_web /rails/letter_opener LetterOpenerWeb::Engine - ci_ci_api_api /ci/api Ci::API::API - ci_lint POST /ci/lint(.:format) ci/lints#create - GET /ci/lint(.:format) ci/lints#show - status_ci_project GET /ci/projects/:id/status(.:format) ci/projects#badge - ci_projects GET /ci/projects(.:format) ci/projects#index - ci_project GET /ci/projects/:id(.:format) ci/projects#show - ci_root GET /ci(.:format) ci/projects#index - GET /oauth/authorize/:code(.:format) oauth/authorizations#show - oauth_authorization GET /oauth/authorize(.:format) oauth/authorizations#new - POST /oauth/authorize(.:format) oauth/authorizations#create - DELETE /oauth/authorize(.:format) oauth/authorizations#destroy - oauth_token POST /oauth/token(.:format) doorkeeper/tokens#create - oauth_revoke POST /oauth/revoke(.:format) doorkeeper/tokens#revoke - oauth_applications GET /oauth/applications(.:format) oauth/applications#index - POST /oauth/applications(.:format) oauth/applications#create - new_oauth_application GET /oauth/applications/new(.:format) oauth/applications#new - edit_oauth_application GET /oauth/applications/:id/edit(.:format) oauth/applications#edit - oauth_application GET /oauth/applications/:id(.:format) oauth/applications#show - PATCH /oauth/applications/:id(.:format) oauth/applications#update - PUT /oauth/applications/:id(.:format) oauth/applications#update - DELETE /oauth/applications/:id(.:format) oauth/applications#destroy - oauth_authorized_applications GET /oauth/authorized_applications(.:format) oauth/authorized_applications#index - oauth_authorized_application DELETE /oauth/authorized_applications/:id(.:format) oauth/authorized_applications#destroy - oauth_token_info GET /oauth/token/info(.:format) doorkeeper/token_info#show - autocomplete_users GET /autocomplete/users(.:format) autocomplete#users - GET /autocomplete/users/:id(.:format) autocomplete#user - autocomplete_projects GET /autocomplete/projects(.:format) autocomplete#projects - emojis GET /emojis(.:format) emojis#index - search GET /search(.:format) search#show - search_autocomplete GET /search/autocomplete(.:format) search#autocomplete - jwt_auth GET /jwt/auth(.:format) jwt#auth - api_api /api API::API - sidekiq /admin/sidekiq Sidekiq::Web - health_check GET /health_check(/:checks)(.:format) health_check#index - help GET /help(.:format) help#index - help_shortcuts GET /help/shortcuts(.:format) help#shortcuts - help_ui GET /help/ui(.:format) help#ui - help_page GET /help/*path(.:format) help#show - koding GET /koding(.:format) koding#index - raw_snippet GET /snippets/:id/raw(.:format) snippets#raw - toggle_award_emoji_snippet POST /snippets/:id/toggle_award_emoji(.:format) snippets#toggle_award_emoji - snippets GET /snippets(.:format) snippets#index - POST /snippets(.:format) snippets#create - new_snippet GET /snippets/new(.:format) snippets#new - edit_snippet GET /snippets/:id/edit(.:format) snippets#edit - snippet GET /snippets/:id(.:format) snippets#show - PATCH /snippets/:id(.:format) snippets#update - PUT /snippets/:id(.:format) snippets#update - DELETE /snippets/:id(.:format) snippets#destroy - GET /s/:username(.:format) redirect(301, /u/%{username}/snippets) {:username=>/[a-zA-Z.0-9_\-]+(?/[A-Za-z0-9_-]+/} - decline_invite GET|POST /invites/:id/decline(.:format) invites#decline {:id=>/[A-Za-z0-9_-]+/} - invite GET /invites/:id(.:format) invites#show {:id=>/[A-Za-z0-9_-]+/} - unsubscribe_sent_notification GET /sent_notifications/:id/unsubscribe(.:format) sent_notifications#unsubscribe {:id=>/\h{32}/} - abuse_reports POST /abuse_reports(.:format) abuse_reports#create - new_abuse_report GET /abuse_reports/new(.:format) abuse_reports#new - notification_settings POST /notification_settings(.:format) notification_settings#create - notification_setting PATCH /notification_settings/:id(.:format) notification_settings#update - PUT /notification_settings/:id(.:format) notification_settings#update - personal_access_token_import_github POST /import/github/personal_access_token(.:format) import/github#personal_access_token - status_import_github GET /import/github/status(.:format) import/github#status - callback_import_github GET /import/github/callback(.:format) import/github#callback - jobs_import_github GET /import/github/jobs(.:format) import/github#jobs - import_github POST /import/github(.:format) import/github#create - new_import_github GET /import/github/new(.:format) import/github#new - status_import_gitlab GET /import/gitlab/status(.:format) import/gitlab#status - callback_import_gitlab GET /import/gitlab/callback(.:format) import/gitlab#callback - jobs_import_gitlab GET /import/gitlab/jobs(.:format) import/gitlab#jobs - import_gitlab POST /import/gitlab(.:format) import/gitlab#create - status_import_bitbucket GET /import/bitbucket/status(.:format) import/bitbucket#status - callback_import_bitbucket GET /import/bitbucket/callback(.:format) import/bitbucket#callback - jobs_import_bitbucket GET /import/bitbucket/jobs(.:format) import/bitbucket#jobs - import_bitbucket POST /import/bitbucket(.:format) import/bitbucket#create - status_import_google_code GET /import/google_code/status(.:format) import/google_code#status - callback_import_google_code POST /import/google_code/callback(.:format) import/google_code#callback - jobs_import_google_code GET /import/google_code/jobs(.:format) import/google_code#jobs - new_user_map_import_google_code GET /import/google_code/user_map(.:format) import/google_code#new_user_map - create_user_map_import_google_code POST /import/google_code/user_map(.:format) import/google_code#create_user_map - import_google_code POST /import/google_code(.:format) import/google_code#create - new_import_google_code GET /import/google_code/new(.:format) import/google_code#new - status_import_fogbugz GET /import/fogbugz/status(.:format) import/fogbugz#status - callback_import_fogbugz POST /import/fogbugz/callback(.:format) import/fogbugz#callback - jobs_import_fogbugz GET /import/fogbugz/jobs(.:format) import/fogbugz#jobs - new_user_map_import_fogbugz GET /import/fogbugz/user_map(.:format) import/fogbugz#new_user_map - create_user_map_import_fogbugz POST /import/fogbugz/user_map(.:format) import/fogbugz#create_user_map - import_fogbugz POST /import/fogbugz(.:format) import/fogbugz#create - new_import_fogbugz GET /import/fogbugz/new(.:format) import/fogbugz#new - import_gitlab_project POST /import/gitlab_project(.:format) import/gitlab_projects#create - POST /import/gitlab_project(.:format) import/gitlab_projects#create - new_import_gitlab_project GET /import/gitlab_project/new(.:format) import/gitlab_projects#new - GET /uploads/:model/:mounted_as/:id/:filename(.:format) uploads#show {:model=>/note|user|group|project/, :mounted_as=>/avatar|attachment/, :filename=>/[^\/]+/} - GET /uploads/:model/:mounted_as/:id/:filename(.:format) uploads#show {:model=>/appearance/, :mounted_as=>/logo|header_logo/, :filename=>/.+/} - GET /uploads/:namespace_id/:project_id/:secret/:filename(.:format) projects/uploads#show {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+/, :filename=>/[^\/]+/} - GET /files/note/:id/:filename(.:format) redirect(301, uploads/note/attachment/%{id}/%{filename}) {:filename=>/[^\/]+/} - trending_explore_projects GET /explore/projects/trending(.:format) explore/projects#trending - starred_explore_projects GET /explore/projects/starred(.:format) explore/projects#starred - explore_projects GET /explore/projects(.:format) explore/projects#index - explore_groups GET /explore/groups(.:format) explore/groups#index - explore_snippets GET /explore/snippets(.:format) explore/snippets#index - explore_root GET /explore(.:format) explore/projects#trending - public GET /public(.:format) explore/projects#index - public_projects GET /public/projects(.:format) explore/projects#index - admin_user_key GET /admin/users/:user_id/keys/:id(.:format) admin/keys#show {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} - DELETE /admin/users/:user_id/keys/:id(.:format) admin/keys#destroy {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} - admin_user_identities GET /admin/users/:user_id/identities(.:format) admin/identities#index {:user_id=>/[a-zA-Z.\/0-9_\-]+/} - POST /admin/users/:user_id/identities(.:format) admin/identities#create {:user_id=>/[a-zA-Z.\/0-9_\-]+/} - new_admin_user_identity GET /admin/users/:user_id/identities/new(.:format) admin/identities#new {:user_id=>/[a-zA-Z.\/0-9_\-]+/} - edit_admin_user_identity GET /admin/users/:user_id/identities/:id/edit(.:format) admin/identities#edit {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} - admin_user_identity PATCH /admin/users/:user_id/identities/:id(.:format) admin/identities#update {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} - PUT /admin/users/:user_id/identities/:id(.:format) admin/identities#update {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} - DELETE /admin/users/:user_id/identities/:id(.:format) admin/identities#destroy {:id=>/[a-zA-Z.\/0-9_\-]+/, :user_id=>/[a-zA-Z.\/0-9_\-]+/} - projects_admin_user GET /admin/users/:id/projects(.:format) admin/users#projects {:id=>/[a-zA-Z.\/0-9_\-]+/} - keys_admin_user GET /admin/users/:id/keys(.:format) admin/users#keys {:id=>/[a-zA-Z.\/0-9_\-]+/} - groups_admin_user GET /admin/users/:id/groups(.:format) admin/users#groups {:id=>/[a-zA-Z.\/0-9_\-]+/} - block_admin_user PUT /admin/users/:id/block(.:format) admin/users#block {:id=>/[a-zA-Z.\/0-9_\-]+/} - unblock_admin_user PUT /admin/users/:id/unblock(.:format) admin/users#unblock {:id=>/[a-zA-Z.\/0-9_\-]+/} - unlock_admin_user PUT /admin/users/:id/unlock(.:format) admin/users#unlock {:id=>/[a-zA-Z.\/0-9_\-]+/} - confirm_admin_user PUT /admin/users/:id/confirm(.:format) admin/users#confirm {:id=>/[a-zA-Z.\/0-9_\-]+/} - impersonate_admin_user POST /admin/users/:id/impersonate(.:format) admin/users#impersonate {:id=>/[a-zA-Z.\/0-9_\-]+/} - disable_two_factor_admin_user PATCH /admin/users/:id/disable_two_factor(.:format) admin/users#disable_two_factor {:id=>/[a-zA-Z.\/0-9_\-]+/} - remove_email_admin_user DELETE /admin/users/:id/remove/:email_id(.:format) admin/users#remove_email {:id=>/[a-zA-Z.\/0-9_\-]+/} - admin_users GET /admin/users(.:format) admin/users#index - POST /admin/users(.:format) admin/users#create - new_admin_user GET /admin/users/new(.:format) admin/users#new - edit_admin_user GET /admin/users/:id/edit(.:format) admin/users#edit {:id=>/[a-zA-Z.\/0-9_\-]+/} - admin_user GET /admin/users/:id(.:format) admin/users#show {:id=>/[a-zA-Z.\/0-9_\-]+/} - PATCH /admin/users/:id(.:format) admin/users#update {:id=>/[a-zA-Z.\/0-9_\-]+/} - PUT /admin/users/:id(.:format) admin/users#update {:id=>/[a-zA-Z.\/0-9_\-]+/} - DELETE /admin/users/:id(.:format) admin/users#destroy {:id=>/[a-zA-Z.\/0-9_\-]+/} - admin_impersonation DELETE /admin/impersonation(.:format) admin/impersonations#destroy - admin_abuse_reports GET /admin/abuse_reports(.:format) admin/abuse_reports#index - admin_abuse_report DELETE /admin/abuse_reports/:id(.:format) admin/abuse_reports#destroy - mark_as_ham_admin_spam_log POST /admin/spam_logs/:id/mark_as_ham(.:format) admin/spam_logs#mark_as_ham - admin_spam_logs GET /admin/spam_logs(.:format) admin/spam_logs#index - admin_spam_log DELETE /admin/spam_logs/:id(.:format) admin/spam_logs#destroy - admin_applications GET /admin/applications(.:format) admin/applications#index - POST /admin/applications(.:format) admin/applications#create - new_admin_application GET /admin/applications/new(.:format) admin/applications#new - edit_admin_application GET /admin/applications/:id/edit(.:format) admin/applications#edit - admin_application GET /admin/applications/:id(.:format) admin/applications#show - PATCH /admin/applications/:id(.:format) admin/applications#update - PUT /admin/applications/:id(.:format) admin/applications#update - DELETE /admin/applications/:id(.:format) admin/applications#destroy - members_update_admin_group PUT /admin/groups/:id/members_update(.:format) admin/groups#members_update {:id=>/[^\/]+/} - admin_groups GET /admin/groups(.:format) admin/groups#index - POST /admin/groups(.:format) admin/groups#create - new_admin_group GET /admin/groups/new(.:format) admin/groups#new - edit_admin_group GET /admin/groups/:id/edit(.:format) admin/groups#edit {:id=>/[^\/]+/} - admin_group GET /admin/groups/:id(.:format) admin/groups#show {:id=>/[^\/]+/} - PATCH /admin/groups/:id(.:format) admin/groups#update {:id=>/[^\/]+/} - PUT /admin/groups/:id(.:format) admin/groups#update {:id=>/[^\/]+/} - DELETE /admin/groups/:id(.:format) admin/groups#destroy {:id=>/[^\/]+/} - admin_deploy_keys GET /admin/deploy_keys(.:format) admin/deploy_keys#index - POST /admin/deploy_keys(.:format) admin/deploy_keys#create - new_admin_deploy_key GET /admin/deploy_keys/new(.:format) admin/deploy_keys#new - admin_deploy_key DELETE /admin/deploy_keys/:id(.:format) admin/deploy_keys#destroy - admin_hook_test GET /admin/hooks/:hook_id/test(.:format) admin/hooks#test - admin_hooks GET /admin/hooks(.:format) admin/hooks#index - POST /admin/hooks(.:format) admin/hooks#create - admin_hook DELETE /admin/hooks/:id(.:format) admin/hooks#destroy - preview_admin_broadcast_messages POST /admin/broadcast_messages/preview(.:format) admin/broadcast_messages#preview - admin_broadcast_messages GET /admin/broadcast_messages(.:format) admin/broadcast_messages#index - POST /admin/broadcast_messages(.:format) admin/broadcast_messages#create - edit_admin_broadcast_message GET /admin/broadcast_messages/:id/edit(.:format) admin/broadcast_messages#edit - admin_broadcast_message PATCH /admin/broadcast_messages/:id(.:format) admin/broadcast_messages#update - PUT /admin/broadcast_messages/:id(.:format) admin/broadcast_messages#update - DELETE /admin/broadcast_messages/:id(.:format) admin/broadcast_messages#destroy - admin_logs GET /admin/logs(.:format) admin/logs#show - admin_health_check GET /admin/health_check(.:format) admin/health_check#show - admin_background_jobs GET /admin/background_jobs(.:format) admin/background_jobs#show - admin_system_info GET /admin/system_info(.:format) admin/system_info#show - admin_requests_profiles GET /admin/requests_profiles(.:format) admin/requests_profiles#index - admin_requests_profile GET /admin/requests_profiles/:name(.:format) admin/requests_profiles#show {:name=>/.+\.html/} - admin_namespaces_projects GET /admin/projects(.:format) admin/projects#index - admin_namespace_projects_root GET /admin/projects/:namespace_id(.:format) admin/projects#show {:namespace_id=>/[a-zA-Z.0-9_\-]+/} - transfer_admin_namespace_project PUT /admin/projects/:namespace_id/:id/transfer(.:format) admin/projects#transfer {:id=>/[a-zA-Z.0-9_\-]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/} - repository_check_admin_namespace_project POST /admin/projects/:namespace_id/:id/repository_check(.:format) admin/projects#repository_check {:id=>/[a-zA-Z.0-9_\-]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/} - admin_namespace_project_runner_projects POST /admin/projects/:namespace_id/:project_id/runner_projects(.:format) admin/runner_projects#create {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+/} - admin_namespace_project_runner_project DELETE /admin/projects/:namespace_id/:project_id/runner_projects/:id(.:format) admin/runner_projects#destroy {:id=>/[a-zA-Z.0-9_\-]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+/} - admin_namespace_projects GET /admin/projects/:namespace_id(.:format) admin/projects#index {:namespace_id=>/[a-zA-Z.0-9_\-]+/} - admin_namespace_project GET /admin/projects/:namespace_id/:id(.:format) admin/projects#show {:id=>/[a-zA-Z.0-9_\-]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/} - preview_admin_appearances GET /admin/appearance/preview(.:format) admin/appearances#preview - logo_admin_appearances DELETE /admin/appearance/logo(.:format) admin/appearances#logo - header_logos_admin_appearances DELETE /admin/appearance/header_logos(.:format) admin/appearances#header_logos - admin_appearances POST /admin/appearance(.:format) admin/appearances#create - GET /admin/appearance(.:format) admin/appearances#show - PATCH /admin/appearance(.:format) admin/appearances#update - PUT /admin/appearance(.:format) admin/appearances#update - admin_application_settings_services GET /admin/application_settings/services(.:format) admin/services#index - edit_admin_application_settings_service GET /admin/application_settings/services/:id/edit(.:format) admin/services#edit - admin_application_settings_service PATCH /admin/application_settings/services/:id(.:format) admin/services#update - PUT /admin/application_settings/services/:id(.:format) admin/services#update - reset_runners_token_admin_application_settings PUT /admin/application_settings/reset_runners_token(.:format) admin/application_settings#reset_runners_token - reset_health_check_token_admin_application_settings PUT /admin/application_settings/reset_health_check_token(.:format) admin/application_settings#reset_health_check_token - clear_repository_check_states_admin_application_settings PUT /admin/application_settings/clear_repository_check_states(.:format) admin/application_settings#clear_repository_check_states - admin_application_settings GET /admin/application_settings(.:format) admin/application_settings#show - PATCH /admin/application_settings(.:format) admin/application_settings#update - PUT /admin/application_settings(.:format) admin/application_settings#update - admin_labels GET /admin/labels(.:format) admin/labels#index - POST /admin/labels(.:format) admin/labels#create - new_admin_label GET /admin/labels/new(.:format) admin/labels#new - edit_admin_label GET /admin/labels/:id/edit(.:format) admin/labels#edit - admin_label GET /admin/labels/:id(.:format) admin/labels#show - PATCH /admin/labels/:id(.:format) admin/labels#update - PUT /admin/labels/:id(.:format) admin/labels#update - DELETE /admin/labels/:id(.:format) admin/labels#destroy - resume_admin_runner GET /admin/runners/:id/resume(.:format) admin/runners#resume - pause_admin_runner GET /admin/runners/:id/pause(.:format) admin/runners#pause - admin_runners GET /admin/runners(.:format) admin/runners#index - admin_runner GET /admin/runners/:id(.:format) admin/runners#show - PATCH /admin/runners/:id(.:format) admin/runners#update - PUT /admin/runners/:id(.:format) admin/runners#update - DELETE /admin/runners/:id(.:format) admin/runners#destroy - cancel_all_admin_builds POST /admin/builds/cancel_all(.:format) admin/builds#cancel_all - admin_builds GET /admin/builds(.:format) admin/builds#index - admin_root GET /admin(.:format) admin/dashboard#index - audit_log_profile GET /profile/audit_log(.:format) profiles#audit_log - applications_profile GET /profile/applications(.:format) oauth/applications#index - reset_private_token_profile PUT /profile/reset_private_token(.:format) profiles#reset_private_token - update_username_profile PUT /profile/update_username(.:format) profiles#update_username - unlink_profile_account DELETE /profile/account/unlink(.:format) profiles/accounts#unlink - profile_account GET /profile/account(.:format) profiles/accounts#show - profile_notifications GET /profile/notifications(.:format) profiles/notifications#show - PATCH /profile/notifications(.:format) profiles/notifications#update - PUT /profile/notifications(.:format) profiles/notifications#update - reset_profile_password PUT /profile/password/reset(.:format) profiles/passwords#reset - profile_password POST /profile/password(.:format) profiles/passwords#create - new_profile_password GET /profile/password/new(.:format) profiles/passwords#new - edit_profile_password GET /profile/password/edit(.:format) profiles/passwords#edit - PATCH /profile/password(.:format) profiles/passwords#update - PUT /profile/password(.:format) profiles/passwords#update - profile_preferences GET /profile/preferences(.:format) profiles/preferences#show - PATCH /profile/preferences(.:format) profiles/preferences#update - PUT /profile/preferences(.:format) profiles/preferences#update - profile_keys GET /profile/keys(.:format) profiles/keys#index - POST /profile/keys(.:format) profiles/keys#create - new_profile_key GET /profile/keys/new(.:format) profiles/keys#new - profile_key GET /profile/keys/:id(.:format) profiles/keys#show - DELETE /profile/keys/:id(.:format) profiles/keys#destroy - profile_emails GET /profile/emails(.:format) profiles/emails#index - POST /profile/emails(.:format) profiles/emails#create - profile_email DELETE /profile/emails/:id(.:format) profiles/emails#destroy - profile_avatar DELETE /profile/avatar(.:format) profiles/avatars#destroy - revoke_profile_personal_access_token PUT /profile/personal_access_tokens/:id/revoke(.:format) profiles/personal_access_tokens#revoke - profile_personal_access_tokens GET /profile/personal_access_tokens(.:format) profiles/personal_access_tokens#index - POST /profile/personal_access_tokens(.:format) profiles/personal_access_tokens#create - create_u2f_profile_two_factor_auth POST /profile/two_factor_auth/create_u2f(.:format) profiles/two_factor_auths#create_u2f - codes_profile_two_factor_auth POST /profile/two_factor_auth/codes(.:format) profiles/two_factor_auths#codes - skip_profile_two_factor_auth PATCH /profile/two_factor_auth/skip(.:format) profiles/two_factor_auths#skip - profile_two_factor_auth POST /profile/two_factor_auth(.:format) profiles/two_factor_auths#create - GET /profile/two_factor_auth(.:format) profiles/two_factor_auths#show - DELETE /profile/two_factor_auth(.:format) profiles/two_factor_auths#destroy - profile_u2f_registration DELETE /profile/u2f_registrations/:id(.:format) profiles/u2f_registrations#destroy - profile GET /profile(.:format) profiles#show - PATCH /profile(.:format) profiles#update - PUT /profile(.:format) profiles#update - user_calendar GET /u/:username/calendar(.:format) users#calendar {:username=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :group_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :group_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :group_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - remove_fork_namespace_project DELETE /:namespace_id/:id/remove_fork(.:format) projects#remove_fork {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - archive_namespace_project POST /:namespace_id/:id/archive(.:format) projects#archive {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - unarchive_namespace_project POST /:namespace_id/:id/unarchive(.:format) projects#unarchive {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - housekeeping_namespace_project POST /:namespace_id/:id/housekeeping(.:format) projects#housekeeping {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - toggle_star_namespace_project POST /:namespace_id/:id/toggle_star(.:format) projects#toggle_star {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - preview_markdown_namespace_project POST /:namespace_id/:id/preview_markdown(.:format) projects#preview_markdown {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - export_namespace_project POST /:namespace_id/:id/export(.:format) projects#export {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - remove_export_namespace_project POST /:namespace_id/:id/remove_export(.:format) projects#remove_export {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - generate_new_export_namespace_project POST /:namespace_id/:id/generate_new_export(.:format) projects#generate_new_export {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - download_export_namespace_project GET /:namespace_id/:id/download_export(.:format) projects#download_export {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - autocomplete_sources_namespace_project GET /:namespace_id/:id/autocomplete_sources(.:format) projects#autocomplete_sources {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - activity_namespace_project GET /:namespace_id/:id/activity(.:format) projects#activity {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - refs_namespace_project GET /:namespace_id/:id/refs(.:format) projects#refs {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - namespace_project_info_refs GET /:namespace_id/:project_id/info/refs(.:format) projects/git_http#info_refs {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} - namespace_project_git_upload_pack POST /:namespace_id/:project_id/git-upload-pack(.:format) projects/git_http#git_upload_pack {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} - namespace_project_git_receive_pack POST /:namespace_id/:project_id/git-receive-pack(.:format) projects/git_http#git_receive_pack {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} - namespace_project_info_lfs_objects_batch POST /:namespace_id/:project_id/info/lfs/objects/batch(.:format) projects/lfs_api#batch {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} - namespace_project_info_lfs_objects POST /:namespace_id/:project_id/info/lfs/objects(.:format) projects/lfs_api#deprecated {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} - GET /:namespace_id/:project_id/info/lfs/objects/*oid(.:format) projects/lfs_api#deprecated {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} - GET /:namespace_id/:project_id/gitlab-lfs/objects/*oid(.:format) projects/lfs_storage#download {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} - PUT /:namespace_id/:project_id/gitlab-lfs/objects/*oid/*size/authorize(.:format) projects/lfs_storage#upload_authorize {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} - PUT /:namespace_id/:project_id/gitlab-lfs/objects/*oid/*size(.:format) projects/lfs_storage#upload_finalize {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :format=>nil, :project_id=>/.+\.git/} - GET /:namespace_id/:project_id/info/refs(.:format) redirect(301) {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?false} - namespace_project_blob GET /:namespace_id/:project_id/blob/*id(.:format) projects/blob#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?false} - DELETE /:namespace_id/:project_id/blob/*id(.:format) projects/blob#destroy {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?false} - PUT /:namespace_id/:project_id/blob/*id(.:format) projects/blob#update {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?false} - POST /:namespace_id/:project_id/blob/*id(.:format) projects/blob#create {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?false} - namespace_project_raw GET /:namespace_id/:project_id/raw/*id(.:format) projects/raw#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/(html|js)/} - namespace_project_tree GET /:namespace_id/:project_id/tree/*id(.:format) projects/tree#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/(html|js)/} - namespace_project_find_file GET /:namespace_id/:project_id/find_file/*id(.:format) projects/find_file#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/html/} - namespace_project_files GET /:namespace_id/:project_id/files/*id(.:format) projects/find_file#list {:id=>/(?:[^.]|\.(?!json$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/json/} - namespace_project_create_dir POST /:namespace_id/:project_id/create_dir/*id(.:format) projects/tree#create_dir {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/(html|js)/} - namespace_project_commits GET /:namespace_id/:project_id/commits/*id(.:format) projects/commits#show {:id=>/(?:[^.]|\.(?!atom$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/atom/} - namespace_project_avatar GET /:namespace_id/:project_id/avatar(.:format) projects/avatars#show {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{7,40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.+/, :to=>/.+/} - namespace_project_network GET /:namespace_id/:project_id/network/:id projects/network#show {:id=>/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\S+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/(zip|tar|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/} - namespace_project_repository POST /:namespace_id/:project_id/repository(.:format) projects/repositories#create {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.*/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/.*/} - commits_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/commits(.:format) projects/merge_requests#commits {:id=>/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\h{40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} - DELETE /:namespace_id/:project_id/merge_requests/:merge_request_id/discussions/:id/resolve(.:format) projects/discussions#unresolve {:id=>/\h{40}/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} - namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#index {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} - browse_namespace_project_build_artifacts GET /:namespace_id/:project_id/builds/:build_id/artifacts/browse(/*path) projects/artifacts#browse {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} - file_namespace_project_build_artifacts GET /:namespace_id/:project_id/builds/:build_id/artifacts/file/*path projects/artifacts#file {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} - keep_namespace_project_build_artifacts POST /:namespace_id/:project_id/builds/:build_id/artifacts/keep(.:format) projects/artifacts#keep {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/} - namespace_project_builds GET /:namespace_id/:project_id/builds(.:format) projects/builds#index {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.\/0-9_\-#%+]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.\/0-9_\-#%+]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.\/0-9_\-#%+]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.\/0-9_\-#%+]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.\/0-9_\-#%+]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/\d+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[^\/]+/} - namespace_project_uploads POST /:namespace_id/:project_id/uploads(.:format) projects/uploads#create {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/svg/} - coverage_namespace_project_badges GET /:namespace_id/:project_id/badges/*ref/coverage(.:format) projects/badges#coverage {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/svg/} - namespace_project_badges GET /:namespace_id/:project_id/badges(.:format) projects/badges#index {:namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - namespace_project GET /:namespace_id/:id(.:format) projects#show {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - PATCH /:namespace_id/:id(.:format) projects#update {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - PUT /:namespace_id/:id(.:format) projects#update {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - DELETE /:namespace_id/:id(.:format) projects#destroy {:id=>/[a-zA-Z.0-9_\-]+(?/[a-zA-Z.0-9_\-]+/} - GET /:username.keys(.:format) profiles/keys#get_keys {:username=>/.*/} - GET /:id(.:format) namespaces#show {:id=>/(?:[^.]|\.(?!atom$))+/, :format=>/atom/} - GET /health_check(/:checks)(.:format) health_check/health_check#index - -Routes for Teaspoon::Engine: - root GET / teaspoon/suite#index -fixture GET /fixtures/*filename(.:format) teaspoon/suite#fixtures - suite GET /:suite(.:format) teaspoon/suite#show {:suite=>"default"} - POST /:suite/:hook(.:format) teaspoon/suite#hook {:suite=>"default", :hook=>"default"} - -Routes for LetterOpenerWeb::Engine: -clear_letters DELETE /clear(.:format) letter_opener_web/letters#clear -delete_letter DELETE /:id(.:format) letter_opener_web/letters#destroy - letters GET / letter_opener_web/letters#index - letter GET /:id(/:style)(.:format) letter_opener_web/letters#show - GET /:id/attachments/:file(.:format) letter_opener_web/letters#attachment diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb index 2ea57e50e76..41d263a46a4 100644 --- a/spec/controllers/snippets_controller_spec.rb +++ b/spec/controllers/snippets_controller_spec.rb @@ -232,26 +232,28 @@ describe SnippetsController do end context 'award emoji on snippets' do - let(:personal_snippet) { create(:personal_snippet, :private, author: user) } + let(:personal_snippet) { create(:personal_snippet, :public, author: user) } + let(:another_user) { create(:user) } before do - sign_in(user) + sign_in(another_user) end describe 'POST #toggle_award_emoji' do it "toggles the award emoji" do expect do post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") - end.to change { personal_snippet.award_emoji.count }.by(1) + end.to change { personal_snippet.award_emoji.count }.from(0).to(1) expect(response.status).to eq(200) end it "removes the already awarded emoji" do post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") + expect do post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") - end.to change { personal_snippet.award_emoji.count }.by(-1) + end.to change { personal_snippet.award_emoji.count }.from(1).to(0) expect(response.status).to eq(200) end diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb index f94ed37ddbc..5ad4fc4865a 100644 --- a/spec/requests/api/award_emoji_spec.rb +++ b/spec/requests/api/award_emoji_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe API::API, api: true do include ApiHelpers let(:user) { create(:user) } - let!(:project) { create(:project) } - let(:issue) { create(:issue, project: project, author: user) } + let!(:project) { create(:empty_project) } + let(:issue) { create(:issue, project: project) } let!(:award_emoji) { create(:award_emoji, awardable: issue, user: user) } let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) } let!(:downvote) { create(:award_emoji, :downvote, awardable: merge_request, user: user) } From 86e7ae82b206b2fd05c886bb1578789554fdb2d1 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Mon, 19 Sep 2016 09:26:37 +0200 Subject: [PATCH 6/8] Use routing concerns to DRY the routes --- config/routes.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 637e5c1bac4..5963e53493b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -35,6 +35,10 @@ Rails.application.routes.draw do post :approve_access_request, on: :member end + concern :awardable do + post :toggle_award_emoji, on: :member + end + namespace :ci do # CI API Ci::API::API.logger Rails.logger @@ -98,10 +102,9 @@ Rails.application.routes.draw do # # Global snippets # - resources :snippets do + resources :snippets, concerns: :awardable do member do get 'raw' - post :toggle_award_emoji end end @@ -662,7 +665,7 @@ Rails.application.routes.draw do end end - resources :snippets, constraints: { id: /\d+/ } do + resources :snippets, concerns: :awardable, constraints: { id: /\d+/ } do member do get 'raw' post :toggle_award_emoji @@ -725,7 +728,7 @@ Rails.application.routes.draw do end end - resources :merge_requests, constraints: { id: /\d+/ } do + resources :merge_requests, concerns: :awardable, constraints: { id: /\d+/ } do member do get :commits get :diffs @@ -737,7 +740,6 @@ Rails.application.routes.draw do post :cancel_merge_when_build_succeeds get :ci_status post :toggle_subscription - post :toggle_award_emoji post :remove_wip get :diff_for_path post :resolve_conflicts @@ -839,10 +841,9 @@ Rails.application.routes.draw do end end - resources :issues, constraints: { id: /\d+/ } do + resources :issues, concerns: :awardable, constraints: { id: /\d+/ } do member do post :toggle_subscription - post :toggle_award_emoji post :mark_as_spam get :referenced_merge_requests get :related_branches @@ -870,9 +871,8 @@ Rails.application.routes.draw do resources :group_links, only: [:index, :create, :destroy], constraints: { id: /\d+/ } - resources :notes, only: [:index, :create, :destroy, :update], constraints: { id: /\d+/ } do + resources :notes, only: [:index, :create, :destroy, :update], concerns: :awardable, constraints: { id: /\d+/ } do member do - post :toggle_award_emoji delete :delete_attachment post :resolve delete :resolve, action: :unresolve From a6e91b1669a99042467173f0305a29dc89b5c8d2 Mon Sep 17 00:00:00 2001 From: Fatih Acet Date: Mon, 19 Sep 2016 20:15:01 +0300 Subject: [PATCH 7/8] Fix styling of award emoji block for snippets after upstream design changes. --- app/assets/stylesheets/pages/snippets.scss | 7 +++++++ .../projects/snippets/_actions.html.haml | 2 +- app/views/projects/snippets/show.html.haml | 21 ++++++++++--------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/app/assets/stylesheets/pages/snippets.scss b/app/assets/stylesheets/pages/snippets.scss index 5270aea4e79..4d5df566d9b 100644 --- a/app/assets/stylesheets/pages/snippets.scss +++ b/app/assets/stylesheets/pages/snippets.scss @@ -12,11 +12,18 @@ .snippet-file-content { border-radius: 3px; + margin-bottom: $gl-padding; + .btn-clipboard { @extend .btn; } } +.project-snippets .awards { + border-bottom: 1px solid $table-border-color; + padding-bottom: $gl-padding; +} + .snippet-title { font-size: 24px; font-weight: 600; diff --git a/app/views/projects/snippets/_actions.html.haml b/app/views/projects/snippets/_actions.html.haml index a5a5619fa12..4aa4ab46a2f 100644 --- a/app/views/projects/snippets/_actions.html.haml +++ b/app/views/projects/snippets/_actions.html.haml @@ -3,7 +3,7 @@ = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: 'btn btn-grouped btn-create new-snippet-link', title: "New Snippet" do New Snippet - if can?(current_user, :update_project_snippet, @snippet) - = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-warning", title: 'Delete Snippet' do + = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-danger", title: 'Delete Snippet' do Delete - if can?(current_user, :update_project_snippet, @snippet) = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-grouped snippable-edit" do diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index 7f72e15ca8f..9503dbded13 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -2,15 +2,16 @@ = render 'shared/snippets/header' -%article.file-holder.snippet-file-content - .file-title - = blob_icon 0, @snippet.file_name - = @snippet.file_name - .file-actions - = clipboard_button(clipboard_target: ".blob-content[data-blob-id='#{@snippet.id}']") - = link_to 'Raw', raw_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-sm", target: "_blank" - = render 'shared/snippets/blob' +.project-snippets + %article.file-holder.snippet-file-content + .file-title + = blob_icon 0, @snippet.file_name + = @snippet.file_name + .file-actions + = clipboard_button(clipboard_target: ".blob-content[data-blob-id='#{@snippet.id}']") + = link_to 'Raw', raw_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-sm", target: "_blank" + = render 'shared/snippets/blob' -= render 'award_emoji/awards_block', awardable: @snippet, inline: true + = render 'award_emoji/awards_block', awardable: @snippet, inline: true -%div#notes= render "projects/notes/notes_with_form" + %div#notes= render "projects/notes/notes_with_form" From e41a3912daaeabe19dc434df8837c9e7d7da7842 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Tue, 20 Sep 2016 21:26:43 +0000 Subject: [PATCH 8/8] Remove duplicate route --- config/routes.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 5963e53493b..80d0adce9c6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -668,7 +668,6 @@ Rails.application.routes.draw do resources :snippets, concerns: :awardable, constraints: { id: /\d+/ } do member do get 'raw' - post :toggle_award_emoji end end