From 71777a4a184945d6b58170af55d9fd9fef821ac9 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 16 May 2017 19:41:15 +0800 Subject: Rename BuildsController to JobsController Rename other URL generators admin_builds_path -> admin_jobs_path Fix tests and more renaming Fix more tests Also change build_id to job_id in the controller --- lib/gitlab/ci/status/build/cancelable.rb | 2 +- lib/gitlab/ci/status/build/common.rb | 2 +- lib/gitlab/ci/status/build/play.rb | 2 +- lib/gitlab/ci/status/build/retryable.rb | 2 +- lib/gitlab/ci/status/build/stop.rb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/ci/status/build/cancelable.rb b/lib/gitlab/ci/status/build/cancelable.rb index 57b533bad99..439ef0ce015 100644 --- a/lib/gitlab/ci/status/build/cancelable.rb +++ b/lib/gitlab/ci/status/build/cancelable.rb @@ -12,7 +12,7 @@ module Gitlab end def action_path - cancel_namespace_project_build_path(subject.project.namespace, + cancel_namespace_project_job_path(subject.project.namespace, subject.project, subject) end diff --git a/lib/gitlab/ci/status/build/common.rb b/lib/gitlab/ci/status/build/common.rb index 3fec2c5d4db..b173c23fba4 100644 --- a/lib/gitlab/ci/status/build/common.rb +++ b/lib/gitlab/ci/status/build/common.rb @@ -8,7 +8,7 @@ module Gitlab end def details_path - namespace_project_build_path(subject.project.namespace, + namespace_project_job_path(subject.project.namespace, subject.project, subject) end diff --git a/lib/gitlab/ci/status/build/play.rb b/lib/gitlab/ci/status/build/play.rb index c6139f1b716..e80f3263794 100644 --- a/lib/gitlab/ci/status/build/play.rb +++ b/lib/gitlab/ci/status/build/play.rb @@ -20,7 +20,7 @@ module Gitlab end def action_path - play_namespace_project_build_path(subject.project.namespace, + play_namespace_project_job_path(subject.project.namespace, subject.project, subject) end diff --git a/lib/gitlab/ci/status/build/retryable.rb b/lib/gitlab/ci/status/build/retryable.rb index 505f80848b2..56303e4cb17 100644 --- a/lib/gitlab/ci/status/build/retryable.rb +++ b/lib/gitlab/ci/status/build/retryable.rb @@ -16,7 +16,7 @@ module Gitlab end def action_path - retry_namespace_project_build_path(subject.project.namespace, + retry_namespace_project_job_path(subject.project.namespace, subject.project, subject) end diff --git a/lib/gitlab/ci/status/build/stop.rb b/lib/gitlab/ci/status/build/stop.rb index 0b5199e5483..2778d6f3b52 100644 --- a/lib/gitlab/ci/status/build/stop.rb +++ b/lib/gitlab/ci/status/build/stop.rb @@ -20,7 +20,7 @@ module Gitlab end def action_path - play_namespace_project_build_path(subject.project.namespace, + play_namespace_project_job_path(subject.project.namespace, subject.project, subject) end -- cgit v1.2.1 From fb3077e67b527f92a917e0f8b6f2745a322bce9a Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 19 May 2017 00:57:37 +0800 Subject: Complete all legacy builds URL. Tests are added --- lib/gitlab/routes/legacy_builds.rb | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 lib/gitlab/routes/legacy_builds.rb (limited to 'lib') diff --git a/lib/gitlab/routes/legacy_builds.rb b/lib/gitlab/routes/legacy_builds.rb new file mode 100644 index 00000000000..ecf0c65d70a --- /dev/null +++ b/lib/gitlab/routes/legacy_builds.rb @@ -0,0 +1,44 @@ + +module Gitlab + module Routes + class LegacyBuilds + def initialize(map) + @map = map + end + + def draw + redirect_builds_to_jobs = @map.redirect(&method(:redirect)) + + @map.get '/builds(/:id(/*action))', to: redirect_builds_to_jobs, + as: 'legacy_build', + format: false + end + + def redirect(params, req) + args = params.values_at(:namespace_id, :project_id, :id).compact + url_helpers = Gitlab::Routing.url_helpers + + if params[:id] + case params[:action] + when 'status' + url_helpers.status_namespace_project_job_path(*args, format: params[:format]) + when 'trace' + url_helpers.trace_namespace_project_job_path(*args, format: params[:format]) + when 'raw' + url_helpers.raw_namespace_project_job_path(*args) + when String + if params[:id] == 'artifacts' + url_helpers.latest_succeeded_namespace_project_artifacts_path(params[:namespace_id], params[:project_id], params[:action], job: req.GET[:job]) + else + "#{url_helpers.namespace_project_job_path(*args)}/#{params[:action]}" + end + else # show + url_helpers.namespace_project_job_path(*args) + end + else # index + url_helpers.namespace_project_jobs_path(*args) + end + end + end + end +end -- cgit v1.2.1 From 876acc7e0d654ebc89df3c596cc504334a37f7d8 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 19 May 2017 14:59:05 +0800 Subject: Separate artifacts from builds, reusing artifacts_action_path --- lib/gitlab/routes/legacy_builds.rb | 49 +++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/routes/legacy_builds.rb b/lib/gitlab/routes/legacy_builds.rb index ecf0c65d70a..2ae6a93981b 100644 --- a/lib/gitlab/routes/legacy_builds.rb +++ b/lib/gitlab/routes/legacy_builds.rb @@ -2,43 +2,60 @@ module Gitlab module Routes class LegacyBuilds + include Gitlab::Routing.url_helpers + include GitlabRoutingHelper + def initialize(map) @map = map end def draw - redirect_builds_to_jobs = @map.redirect(&method(:redirect)) + redirect_artifacts = @map.redirect(&method(:redirect_artifacts)) + redirect_builds = @map.redirect(&method(:redirect_builds)) + + @map.get '/builds(/:id)/artifacts/*action', to: redirect_artifacts, + as: 'legacy_artifacts', + format: false - @map.get '/builds(/:id(/*action))', to: redirect_builds_to_jobs, - as: 'legacy_build', + @map.get '/builds(/:id(/*action))', to: redirect_builds, + as: 'legacy_builds', format: false end - def redirect(params, req) + private + + def redirect_artifacts(params, req) + if params[:id] + project = fake_project(*params.values_at(:namespace_id, :project_id)) + + artifacts_action_path(params[:action], project, params[:id]) + else + latest_succeeded_namespace_project_artifacts_path(params[:namespace_id], params[:project_id], params[:action], job: req.GET[:job]) + end + end + + def redirect_builds(params, req) args = params.values_at(:namespace_id, :project_id, :id).compact - url_helpers = Gitlab::Routing.url_helpers if params[:id] case params[:action] when 'status' - url_helpers.status_namespace_project_job_path(*args, format: params[:format]) + status_namespace_project_job_path(*args, format: params[:format]) when 'trace' - url_helpers.trace_namespace_project_job_path(*args, format: params[:format]) + trace_namespace_project_job_path(*args, format: params[:format]) when 'raw' - url_helpers.raw_namespace_project_job_path(*args) - when String - if params[:id] == 'artifacts' - url_helpers.latest_succeeded_namespace_project_artifacts_path(params[:namespace_id], params[:project_id], params[:action], job: req.GET[:job]) - else - "#{url_helpers.namespace_project_job_path(*args)}/#{params[:action]}" - end + raw_namespace_project_job_path(*args) else # show - url_helpers.namespace_project_job_path(*args) + namespace_project_job_path(*args) end else # index - url_helpers.namespace_project_jobs_path(*args) + namespace_project_jobs_path(*args) end end + + def fake_project(namespace_id, project_id) + Struct.new(:namespace, :to_param).new(namespace_id, project_id) + end end end end -- cgit v1.2.1 From 43981250c426595c9b3c03a5153ae05d3de2a8e2 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 23 May 2017 21:20:59 +0800 Subject: Use controllers to redirect --- lib/gitlab/routes/legacy_builds.rb | 68 ++++++++++++++------------------------ 1 file changed, 24 insertions(+), 44 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/routes/legacy_builds.rb b/lib/gitlab/routes/legacy_builds.rb index 2ae6a93981b..cbb8b960c7e 100644 --- a/lib/gitlab/routes/legacy_builds.rb +++ b/lib/gitlab/routes/legacy_builds.rb @@ -1,4 +1,3 @@ - module Gitlab module Routes class LegacyBuilds @@ -10,52 +9,33 @@ module Gitlab end def draw - redirect_artifacts = @map.redirect(&method(:redirect_artifacts)) - redirect_builds = @map.redirect(&method(:redirect_builds)) - - @map.get '/builds(/:id)/artifacts/*action', to: redirect_artifacts, - as: 'legacy_artifacts', - format: false - - @map.get '/builds(/:id(/*action))', to: redirect_builds, - as: 'legacy_builds', - format: false - end - - private - - def redirect_artifacts(params, req) - if params[:id] - project = fake_project(*params.values_at(:namespace_id, :project_id)) - - artifacts_action_path(params[:action], project, params[:id]) - else - latest_succeeded_namespace_project_artifacts_path(params[:namespace_id], params[:project_id], params[:action], job: req.GET[:job]) - end - end - - def redirect_builds(params, req) - args = params.values_at(:namespace_id, :project_id, :id).compact - - if params[:id] - case params[:action] - when 'status' - status_namespace_project_job_path(*args, format: params[:format]) - when 'trace' - trace_namespace_project_job_path(*args, format: params[:format]) - when 'raw' - raw_namespace_project_job_path(*args) - else # show - namespace_project_job_path(*args) + @map.instance_eval do + resources :builds, only: [:index, :show], constraints: { id: /\d+/ } do + collection do + resources :artifacts, only: [], controller: 'build_artifacts' do + collection do + get :latest_succeeded, + path: '*ref_name_and_path', + format: false + end + end + end + + member do + get :status + get :trace, defaults: { format: 'json' } + get :raw + end + + resource :artifacts, only: [], controller: 'build_artifacts' do + get :download + get :browse, path: 'browse(/*path)', format: false + get :file, path: 'file/*path', format: false + get :raw, path: 'raw/*path', format: false + end end - else # index - namespace_project_jobs_path(*args) end end - - def fake_project(namespace_id, project_id) - Struct.new(:namespace, :to_param).new(namespace_id, project_id) - end end end end -- cgit v1.2.1 From 524c947eafbc4b710ac862c4e90801b2777d49dc Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 23 May 2017 23:42:26 +0800 Subject: Add checks before redirect, remove status/trace compatible urls, which were for javascripts --- lib/gitlab/routes/legacy_builds.rb | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/routes/legacy_builds.rb b/lib/gitlab/routes/legacy_builds.rb index cbb8b960c7e..1b6f6df26a2 100644 --- a/lib/gitlab/routes/legacy_builds.rb +++ b/lib/gitlab/routes/legacy_builds.rb @@ -22,8 +22,6 @@ module Gitlab end member do - get :status - get :trace, defaults: { format: 'json' } get :raw end -- cgit v1.2.1 From ec525efddba67d840cc409aa4b9a8857dac7453f Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 23 May 2017 23:43:48 +0800 Subject: Routing helpers are no longer needed --- lib/gitlab/routes/legacy_builds.rb | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/routes/legacy_builds.rb b/lib/gitlab/routes/legacy_builds.rb index 1b6f6df26a2..36d1a8a6f64 100644 --- a/lib/gitlab/routes/legacy_builds.rb +++ b/lib/gitlab/routes/legacy_builds.rb @@ -1,9 +1,6 @@ module Gitlab module Routes class LegacyBuilds - include Gitlab::Routing.url_helpers - include GitlabRoutingHelper - def initialize(map) @map = map end -- cgit v1.2.1 From c94db0c2906c5da49acc9addb976b64fd7c7b256 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 26 May 2017 21:55:29 +0800 Subject: Use - as the prefix so we don't conflict with namespaces The decision was made around: https://gitlab.com/gitlab-org/gitlab-ce/issues/26407#note_30624641 --- lib/gitlab/path_regex.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/gitlab/path_regex.rb b/lib/gitlab/path_regex.rb index 1c0abc9f7cf..9ff6829cd49 100644 --- a/lib/gitlab/path_regex.rb +++ b/lib/gitlab/path_regex.rb @@ -80,6 +80,7 @@ module Gitlab # By rejecting `badges` the router can _count_ on the fact that `badges` will # be preceded by the `namespace/project`. PROJECT_WILDCARD_ROUTES = %w[ + - badges blame blob -- cgit v1.2.1 From 366cf1f5d33184f87b714bdba2a3025b9cb39be1 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Sat, 27 May 2017 02:12:35 +0800 Subject: Should escape the routes because we added - --- lib/gitlab/etag_caching/router.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/etag_caching/router.rb b/lib/gitlab/etag_caching/router.rb index cc285162b44..d137cc1bae6 100644 --- a/lib/gitlab/etag_caching/router.rb +++ b/lib/gitlab/etag_caching/router.rb @@ -11,7 +11,7 @@ module Gitlab USED_IN_ROUTES = %w[noteable issue notes issues realtime_changes commit pipelines merge_requests new].freeze RESERVED_WORDS = Gitlab::PathRegex::ILLEGAL_PROJECT_PATH_WORDS - USED_IN_ROUTES - RESERVED_WORDS_REGEX = Regexp.union(*RESERVED_WORDS) + RESERVED_WORDS_REGEX = Regexp.union(*RESERVED_WORDS.map(&Regexp.method(:escape))) ROUTES = [ Gitlab::EtagCaching::Router::Route.new( %r(^(?!.*(#{RESERVED_WORDS_REGEX})).*/noteable/issue/\d+/notes\z), -- cgit v1.2.1 From 98043aeedf1fe3241d8362d8036f28b709e6d468 Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Mon, 22 May 2017 16:42:10 +0200 Subject: Copy `filter_projects` helper to V3 The helper will be modified in V4, so copy the original to V4 to keep the current behavior in V3. --- lib/api/v3/helpers.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'lib') diff --git a/lib/api/v3/helpers.rb b/lib/api/v3/helpers.rb index 0f234d4cdad..06af286ef50 100644 --- a/lib/api/v3/helpers.rb +++ b/lib/api/v3/helpers.rb @@ -14,6 +14,33 @@ module API authorize! access_level, merge_request merge_request end + + # project helpers + + def filter_projects(projects) + if params[:membership] + projects = projects.merge(current_user.authorized_projects) + end + + if params[:owned] + projects = projects.merge(current_user.owned_projects) + end + + if params[:starred] + projects = projects.merge(current_user.starred_projects) + end + + if params[:search].present? + projects = projects.search(params[:search]) + end + + if params[:visibility].present? + projects = projects.search_by_visibility(params[:visibility]) + end + + projects = projects.where(archived: params[:archived]) + projects.reorder(params[:order_by] => params[:sort]) + end end end end -- cgit v1.2.1 From 44fdf0a1e314da517d189e356b0e44bb63cf0f4b Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Mon, 22 May 2017 16:47:16 +0200 Subject: Move ProjectsFinder to `present_projects` for simplification To avoid passing parameters double, move all filtering to the `present_projects` helper. --- lib/api/projects.rb | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/api/projects.rb b/lib/api/projects.rb index d4fe5c023bf..fce496308c3 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -67,20 +67,18 @@ module API optional :import_url, type: String, desc: 'URL from which the project is imported' end - def present_projects(projects, options = {}) + def present_projects(options = {}) options = options.reverse_merge( - with: Entities::Project, - current_user: current_user, - simple: params[:simple], - with_issues_enabled: params[:with_issues_enabled], - with_merge_requests_enabled: params[:with_merge_requests_enabled] + with: current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails, + current_user: current_user ) + projects = ProjectsFinder.new(current_user: current_user).execute projects = filter_projects(projects) - projects = projects.with_statistics if options[:statistics] - projects = projects.with_issues_enabled if options[:with_issues_enabled] - projects = projects.with_merge_requests_enabled if options[:with_merge_requests_enabled] - options[:with] = Entities::BasicProjectDetails if options[:simple] + projects = projects.with_statistics if params[:statistics] + projects = projects.with_issues_enabled if params[:with_issues_enabled] + projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled] + options[:with] = Entities::BasicProjectDetails if params[:simple] present paginate(projects), options end @@ -94,8 +92,7 @@ module API use :statistics_params end get do - entity = current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails - present_projects ProjectsFinder.new(current_user: current_user).execute, with: entity, statistics: params[:statistics] + present_projects end desc 'Create new project' do -- cgit v1.2.1 From 4fda13b68eb7da27be5e74cac6d3d537502b19f7 Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Mon, 22 May 2017 16:48:38 +0200 Subject: Build options hash after finding the list of projects Because this order makes more sense and makes the code easier to read. --- lib/api/projects.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/api/projects.rb b/lib/api/projects.rb index fce496308c3..ef09dfa0102 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -68,16 +68,17 @@ module API end def present_projects(options = {}) - options = options.reverse_merge( - with: current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails, - current_user: current_user - ) - projects = ProjectsFinder.new(current_user: current_user).execute projects = filter_projects(projects) projects = projects.with_statistics if params[:statistics] projects = projects.with_issues_enabled if params[:with_issues_enabled] projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled] + + options = options.reverse_merge( + with: current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails, + statistics: params[:statistics], + current_user: current_user + ) options[:with] = Entities::BasicProjectDetails if params[:simple] present paginate(projects), options -- cgit v1.2.1 From 07fc79e7c53a4fa7c4dd33835b905dfa8a609ff8 Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Tue, 23 May 2017 15:48:13 +0200 Subject: Handle `membership` in ProjectFinder The ProjectFinder supports the `non_public` parameter. This can be used to find only projects the user is member of. --- lib/api/helpers.rb | 4 ---- lib/api/projects.rb | 5 ++++- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 226a7ddd50e..0dc33eb2097 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -257,10 +257,6 @@ module API # project helpers def filter_projects(projects) - if params[:membership] - projects = projects.merge(current_user.authorized_projects) - end - if params[:owned] projects = projects.merge(current_user.owned_projects) end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index ef09dfa0102..bb03480f1ee 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -68,7 +68,10 @@ module API end def present_projects(options = {}) - projects = ProjectsFinder.new(current_user: current_user).execute + finder_params = {} + finder_params[:non_public] = true if params[:membership].present? + + projects = ProjectsFinder.new(current_user: current_user, params: finder_params).execute projects = filter_projects(projects) projects = projects.with_statistics if params[:statistics] projects = projects.with_issues_enabled if params[:with_issues_enabled] -- cgit v1.2.1 From a1deed629e03d8db47deb1bcf795ae8abaf2c847 Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Tue, 23 May 2017 22:40:39 +0200 Subject: Use ProjectFinder to filter the projects Instead of trying to do the heavy lifting in the API itself, use the existing features of the ProjectFinder. --- lib/api/helpers.rb | 13 ------------- lib/api/projects.rb | 4 ++++ 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 0dc33eb2097..2855bd7385d 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -261,19 +261,6 @@ module API projects = projects.merge(current_user.owned_projects) end - if params[:starred] - projects = projects.merge(current_user.starred_projects) - end - - if params[:search].present? - projects = projects.search(params[:search]) - end - - if params[:visibility].present? - projects = projects.search_by_visibility(params[:visibility]) - end - - projects = projects.where(archived: params[:archived]) projects.reorder(params[:order_by] => params[:sort]) end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index bb03480f1ee..7610e3cbacc 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -70,6 +70,10 @@ module API def present_projects(options = {}) finder_params = {} finder_params[:non_public] = true if params[:membership].present? + finder_params[:starred] = true if params[:starred].present? + finder_params[:visibility_level] = Gitlab::VisibilityLevel.level_value(params[:visibility]) if params[:visibility] + finder_params[:archived] = params[:archived] + finder_params[:search] = params[:search] if params[:search] projects = ProjectsFinder.new(current_user: current_user, params: finder_params).execute projects = filter_projects(projects) -- cgit v1.2.1 From 0f0b9a8466747f69e210fc27778f96ab8ef628bc Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Wed, 24 May 2017 22:12:40 +0200 Subject: Use helper to construct Finder params The ProjectsFinder and GroupFinder both support the same set of params. And the `/api/v4/projects` and `/api/v4/group/:id/projects` also support the same set of params. But they do not match the Finder params. So use a helper method to transform them. --- lib/api/groups.rb | 2 +- lib/api/helpers.rb | 10 ++++++++++ lib/api/projects.rb | 9 +-------- 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/api/groups.rb b/lib/api/groups.rb index ee85b777aff..aacc3356a0e 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -151,7 +151,7 @@ module API end get ":id/projects" do group = find_group!(params[:id]) - projects = GroupProjectsFinder.new(group: group, current_user: current_user).execute + projects = GroupProjectsFinder.new(group: group, current_user: current_user, params: project_finder_params).execute projects = filter_projects(projects) entity = params[:simple] ? Entities::BasicProjectDetails : Entities::Project present paginate(projects), with: entity, current_user: current_user diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 2855bd7385d..17f57cfb8d7 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -264,6 +264,16 @@ module API projects.reorder(params[:order_by] => params[:sort]) end + def project_finder_params + finder_params = {} + finder_params[:non_public] = true if params[:membership].present? + finder_params[:starred] = true if params[:starred].present? + finder_params[:visibility_level] = Gitlab::VisibilityLevel.level_value(params[:visibility]) if params[:visibility] + finder_params[:archived] = params[:archived] + finder_params[:search] = params[:search] if params[:search] + finder_params + end + # file helpers def uploaded_file(field, uploads_path) diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 7610e3cbacc..267dd2a74d7 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -68,14 +68,7 @@ module API end def present_projects(options = {}) - finder_params = {} - finder_params[:non_public] = true if params[:membership].present? - finder_params[:starred] = true if params[:starred].present? - finder_params[:visibility_level] = Gitlab::VisibilityLevel.level_value(params[:visibility]) if params[:visibility] - finder_params[:archived] = params[:archived] - finder_params[:search] = params[:search] if params[:search] - - projects = ProjectsFinder.new(current_user: current_user, params: finder_params).execute + projects = ProjectsFinder.new(current_user: current_user, params: project_finder_params).execute projects = filter_projects(projects) projects = projects.with_statistics if params[:statistics] projects = projects.with_issues_enabled if params[:with_issues_enabled] -- cgit v1.2.1 From db679788e46d55984a4af71034c6db11aed919e4 Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Fri, 26 May 2017 16:31:37 +0200 Subject: Add :owned param to ProjectFinder And use it in the API. --- lib/api/groups.rb | 2 +- lib/api/helpers.rb | 7 ++----- lib/api/projects.rb | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/api/groups.rb b/lib/api/groups.rb index aacc3356a0e..e14a988a153 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -152,7 +152,7 @@ module API get ":id/projects" do group = find_group!(params[:id]) projects = GroupProjectsFinder.new(group: group, current_user: current_user, params: project_finder_params).execute - projects = filter_projects(projects) + projects = reorder_projects(projects) entity = params[:simple] ? Entities::BasicProjectDetails : Entities::Project present paginate(projects), with: entity, current_user: current_user end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 17f57cfb8d7..d61450f8258 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -256,16 +256,13 @@ module API # project helpers - def filter_projects(projects) - if params[:owned] - projects = projects.merge(current_user.owned_projects) - end - + def reorder_projects(projects) projects.reorder(params[:order_by] => params[:sort]) end def project_finder_params finder_params = {} + finder_params[:owned] = true if params[:owned].present? finder_params[:non_public] = true if params[:membership].present? finder_params[:starred] = true if params[:starred].present? finder_params[:visibility_level] = Gitlab::VisibilityLevel.level_value(params[:visibility]) if params[:visibility] diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 267dd2a74d7..1356f959e70 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -69,7 +69,7 @@ module API def present_projects(options = {}) projects = ProjectsFinder.new(current_user: current_user, params: project_finder_params).execute - projects = filter_projects(projects) + projects = reorder_projects(projects) projects = projects.with_statistics if params[:statistics] projects = projects.with_issues_enabled if params[:with_issues_enabled] projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled] -- cgit v1.2.1 From 0c7dd30c78043ea3d4629e1e5739ccfcc7d968fe Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 30 May 2017 16:19:29 -0500 Subject: Make .gitmodules parsing more resilient to syntax errors --- lib/gitlab/git/repository.rb | 46 +++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index b9f1ac144b6..c3bf32ca1cc 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -1008,25 +1008,34 @@ module Gitlab def parse_gitmodules(commit, content) results = {} - current = "" - content.split("\n").each do |txt| - if txt =~ /^\s*\[/ - current = txt.match(/(?<=").*(?=")/)[0] - results[current] = {} - else - next unless results[current] - match_data = txt.match(/(\w+)\s*=\s*(.*)/) - next unless match_data - target = match_data[2].chomp - results[current][match_data[1]] = target - - if match_data[1] == "path" + name = nil + entry = nil + content.each_line do |line| + case line.strip + when /\A\[submodule "(?[^"]+)"\]\z/ # Submodule header + name = $~[:name] + entry = results[name] = {} + when /\A(?\w+)\s*=\s*(?.*)\z/ # Key/value pair + key = $~[:key] + value = $~[:value].chomp + + next unless name && entry + + entry[key] = value + + if key == 'path' begin - results[current]["id"] = blob_content(commit, target) + entry['id'] = blob_content(commit, value) rescue InvalidBlobName - results.delete(current) + # The current entry is invalid + results.delete(name) + name = entry = nil end end + when /\A#/ # Comment + next + else # Invalid line + name = entry = nil end end @@ -1086,7 +1095,12 @@ module Gitlab elsif tmp_entry.nil? return nil else - tmp_entry = rugged.lookup(tmp_entry[:oid]) + begin + tmp_entry = rugged.lookup(tmp_entry[:oid]) + rescue Rugged::OdbError, Rugged::InvalidError, Rugged::ReferenceError + return nil + end + return nil unless tmp_entry.type == :tree tmp_entry = tmp_entry[dir] end -- cgit v1.2.1 From 1e5506d01619780da68fc51ada58188a9070255b Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Tue, 30 May 2017 23:24:17 +0200 Subject: Remove some deprecated methods To avoid the use of slow queries, remove some deprecated methods and encourage the use of ProjectFinder to find projects. --- lib/api/v3/helpers.rb | 2 +- lib/api/v3/projects.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/api/v3/helpers.rb b/lib/api/v3/helpers.rb index 06af286ef50..d9e76560d03 100644 --- a/lib/api/v3/helpers.rb +++ b/lib/api/v3/helpers.rb @@ -35,7 +35,7 @@ module API end if params[:visibility].present? - projects = projects.search_by_visibility(params[:visibility]) + projects = projects.where(visibility_level: Gitlab::VisibilityLevel.level_value(params[:visibility])) end projects = projects.where(archived: params[:archived]) diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index 164612cb8dd..896c00b88e7 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -147,7 +147,7 @@ module API get '/starred' do authenticate! - present_projects current_user.viewable_starred_projects + present_projects ProjectsFinder.new(current_user: current_user, params: { starred: true }).execute end desc 'Get all projects for admin user' do -- cgit v1.2.1 From 0684073d1ea5de0c7e0052b3ccc0cca77f661b56 Mon Sep 17 00:00:00 2001 From: vanadium23 Date: Tue, 30 May 2017 20:41:43 +0300 Subject: Add tag_list param to project api --- lib/api/projects.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/api/projects.rb b/lib/api/projects.rb index d4fe5c023bf..a827fb26b98 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -21,6 +21,7 @@ module API optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access' optional :only_allow_merge_if_pipeline_succeeds, type: Boolean, desc: 'Only allow to merge if builds succeed' optional :only_allow_merge_if_all_discussions_are_resolved, type: Boolean, desc: 'Only allow to merge if all discussions are resolved' + optional :tag_list, type: Array[String], desc: 'The list of tags for a project' end params :optional_params do @@ -231,6 +232,7 @@ module API :request_access_enabled, :shared_runners_enabled, :snippets_enabled, + :tag_list, :visibility, :wiki_enabled ] -- cgit v1.2.1 From ea7269e4c66a51eb4c66b9022ba4c2b35d8ad012 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 31 May 2017 11:19:56 -0500 Subject: Remove entry variable --- lib/gitlab/git/repository.rb | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index c3bf32ca1cc..9d6adbdb4ac 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -1006,40 +1006,39 @@ module Gitlab # Parses the contents of a .gitmodules file and returns a hash of # submodule information. def parse_gitmodules(commit, content) - results = {} + modules = {} name = nil - entry = nil content.each_line do |line| case line.strip when /\A\[submodule "(?[^"]+)"\]\z/ # Submodule header name = $~[:name] - entry = results[name] = {} + modules[name] = {} when /\A(?\w+)\s*=\s*(?.*)\z/ # Key/value pair key = $~[:key] value = $~[:value].chomp - next unless name && entry + next unless name && modules[name] - entry[key] = value + modules[name][key] = value if key == 'path' begin - entry['id'] = blob_content(commit, value) + modules[name]['id'] = blob_content(commit, value) rescue InvalidBlobName # The current entry is invalid - results.delete(name) - name = entry = nil + modules.delete(name) + name = nil end end when /\A#/ # Comment next else # Invalid line - name = entry = nil + name = nil end end - results + modules end # Returns true if +commit+ introduced changes to +path+, using commit -- cgit v1.2.1 From 671284ba375109becbfa2a288032cdc7301b157b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Wed, 31 May 2017 21:06:01 +0000 Subject: Add feature toggles through Flipper --- lib/api/api.rb | 1 + lib/api/entities.rb | 22 ++++++++++++++++++++++ lib/api/features.rb | 36 ++++++++++++++++++++++++++++++++++++ lib/feature.rb | 41 +++++++++++++++++++++++++++++++++++++++++ lib/gitlab/gitaly_client.rb | 22 ++++++++++++++++++++-- 5 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 lib/api/features.rb create mode 100644 lib/feature.rb (limited to 'lib') diff --git a/lib/api/api.rb b/lib/api/api.rb index bbdd2039f43..7ae2f3cad40 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -94,6 +94,7 @@ module API mount ::API::DeployKeys mount ::API::Deployments mount ::API::Environments + mount ::API::Features mount ::API::Files mount ::API::Groups mount ::API::Internal diff --git a/lib/api/entities.rb b/lib/api/entities.rb index e10bd230ae2..fc8183a62c1 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -753,6 +753,28 @@ module API expose :impersonation end + class FeatureGate < Grape::Entity + expose :key + expose :value + end + + class Feature < Grape::Entity + expose :name + expose :state + expose :gates, using: FeatureGate do |model| + model.gates.map do |gate| + value = model.gate_values[gate.key] + + # By default all gate values are populated. Only show relevant ones. + if (value.is_a?(Integer) && value.zero?) || (value.is_a?(Set) && value.empty?) + next + end + + { key: gate.key, value: value } + end.compact + end + end + module JobRequest class JobInfo < Grape::Entity expose :name, :stage diff --git a/lib/api/features.rb b/lib/api/features.rb new file mode 100644 index 00000000000..cff0ba2ddff --- /dev/null +++ b/lib/api/features.rb @@ -0,0 +1,36 @@ +module API + class Features < Grape::API + before { authenticated_as_admin! } + + resource :features do + desc 'Get a list of all features' do + success Entities::Feature + end + get do + features = Feature.all + + present features, with: Entities::Feature, current_user: current_user + end + + desc 'Set the gate value for the given feature' do + success Entities::Feature + end + params do + requires :value, type: String, desc: '`true` or `false` to enable/disable, an integer for percentage of time' + end + post ':name' do + feature = Feature.get(params[:name]) + + if %w(0 false).include?(params[:value]) + feature.disable + elsif params[:value] == 'true' + feature.enable + else + feature.enable_percentage_of_time(params[:value].to_i) + end + + present feature, with: Entities::Feature, current_user: current_user + end + end + end +end diff --git a/lib/feature.rb b/lib/feature.rb new file mode 100644 index 00000000000..2e2b343f82c --- /dev/null +++ b/lib/feature.rb @@ -0,0 +1,41 @@ +require 'flipper/adapters/active_record' + +class Feature + # Classes to override flipper table names + class FlipperFeature < Flipper::Adapters::ActiveRecord::Feature + # Using `self.table_name` won't work. ActiveRecord bug? + superclass.table_name = 'features' + end + + class FlipperGate < Flipper::Adapters::ActiveRecord::Gate + superclass.table_name = 'feature_gates' + end + + class << self + def all + flipper.features.to_a + end + + def get(key) + flipper.feature(key) + end + + def persisted?(feature) + # Flipper creates on-memory features when asked for a not-yet-created one. + # If we want to check if a feature has been actually set, we look for it + # on the persisted features list. + all.map(&:name).include?(feature.name) + end + + private + + def flipper + @flipper ||= begin + adapter = Flipper::Adapters::ActiveRecord.new( + feature_class: FlipperFeature, gate_class: FlipperGate) + + Flipper.new(adapter) + end + end + end +end diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb index 72466700c05..2343446bf22 100644 --- a/lib/gitlab/gitaly_client.rb +++ b/lib/gitlab/gitaly_client.rb @@ -2,6 +2,12 @@ require 'gitaly' module Gitlab module GitalyClient + module MigrationStatus + DISABLED = 1 + OPT_IN = 2 + OPT_OUT = 3 + end + SERVER_VERSION_FILE = 'GITALY_SERVER_VERSION'.freeze MUTEX = Mutex.new @@ -46,8 +52,20 @@ module Gitlab Gitlab.config.gitaly.enabled end - def self.feature_enabled?(feature) - enabled? && ENV["GITALY_#{feature.upcase}"] == '1' + def self.feature_enabled?(feature, status: MigrationStatus::OPT_IN) + return false if !enabled? || status == MigrationStatus::DISABLED + + feature = Feature.get("gitaly_#{feature}") + + # If the feature hasn't been set, turn it on if it's opt-out + return status == MigrationStatus::OPT_OUT unless Feature.persisted?(feature) + + if feature.percentage_of_time_value > 0 + # Probabilistically enable this feature + return Random.rand() * 100 < feature.percentage_of_time_value + end + + feature.enabled? end def self.migrate(feature) -- cgit v1.2.1